Hebrew date conversion code - ignore if you're not interested
- From: rms39 columbia edu (Russell Steinthal)
- To: calendar-list gnome org
- Subject: Hebrew date conversion code - ignore if you're not interested
- Date: Sun, 06 Feb 2000 11:11:14 -0500
// Luach - a Jewish calendar with halachic times
// Copyright (C) Russell Steinthal, 1999
// See file COPYING for license information
// Implementation of Hebrew date class
// $Header$
// Code in this file is derived from code bearing the following
license:
/////////// The following C++ code is translated from the Lisp code
/////////// in ``Calendrical Calculations'' by Nachum Dershowitz and
/////////// Edward M. Reingold, Software---Practice & Experience,
/////////// vol. 20, no. 9 (September, 1990), pp. 899--928.
/////////// This code is in the public domain, but any use of it
/////////// should publically acknowledge its source.
#include "Date.h"
static const int HebrewEpoch = -1373429;
HebrewDate::HebrewDate(const SimpleDate& d)
{
int abs;
if(d.type == Gregorian)
abs = (int) GregorianDate(d.d,d.m,d.y);
else
abs = (int) HebrewDate(d.d,d.m,d.y);
FromAbsolute(abs);
}
HebrewDate::HebrewDate(const GregorianDate& d)
{
FromAbsolute(d);
}
void HebrewDate::FromGregorian(int day, int month, int year)
{
int abs = (int) GregorianDate(day, month, year);
FromAbsolute(abs);
}
// Number of days elapsed from the Sunday prior to the start of the
// Hebrew calendar to the mean conjunction of Tishri of Hebrew year.
int HebrewDate::DaysFromCreation(int year) const
{
int MonthsElapsed =
(235 * ((year - 1) / 19)) // Months in complete cycles
so far.
+ (12 * ((year - 1) % 19)) // Regular months in this
cycle.
+ (7 * ((year - 1) % 19) + 1) / 19; // Leap months this cycle
int PartsElapsed = 204 + 793 * (MonthsElapsed % 1080);
int HoursElapsed =
5 + 12 * MonthsElapsed + 793 * (MonthsElapsed / 1080)
+ PartsElapsed / 1080;
int ConjunctionDay = 1 + 29 * MonthsElapsed + HoursElapsed / 24;
int ConjunctionParts = 1080 * (HoursElapsed % 24) + PartsElapsed %
1080;
int AlternativeDay;
if ((ConjunctionParts >= 19440) // If new moon is at or
after midday,
|| (((ConjunctionDay % 7) == 2) // ...or is on a Tuesday...
&& (ConjunctionParts >= 9924) // at 9 hours, 204 parts or
later...
&& !(IsLeapYear(year))) // ...of a common year,
|| (((ConjunctionDay % 7) == 1) // ...or is on a Monday at...
&& (ConjunctionParts >= 16789) // 15 hours, 589 parts or
later...
&& (IsLeapYear(year - 1))))// at the end of a leap year
// Then postpone Rosh HaShanah one day
AlternativeDay = ConjunctionDay + 1;
else
AlternativeDay = ConjunctionDay;
if (((AlternativeDay % 7) == 0)// If Rosh HaShanah would occur on
Sunday,
|| ((AlternativeDay % 7) == 3) // or Wednesday,
|| ((AlternativeDay % 7) == 5)) // or Friday
// Then postpone it one (more) day
return (1+ AlternativeDay);
else
return AlternativeDay;
}
inline bool HebrewDate::IsLeapYear(int year) const
{
return ((((7 * year) + 1) % 19) < 7);
}
inline bool HebrewDate::LongHeshvan(int year) const
{
return ((DaysInYear(year) % 10) == 5);
}
inline bool HebrewDate::ShortKislev(int year) const
{
return ((DaysInYear(year) % 10) == 3);
}
inline int HebrewDate::DaysInYear(int year) const
{
return DaysFromCreation(year+1)-DaysFromCreation(year);
}
inline int HebrewDate::LastDayOfMonth(int month, int year) const
{
switch(month)
{
case 2:
case 4:
case 6:
case 10:
case 13:
return 29;
case 8:
return LongHeshvan(year) ? 30 : 29;
case 9:
return ShortKislev(year) ? 29 : 30;
case 12:
return IsLeapYear(year) ? 30 : 29;
}
return 30;
}
inline int HebrewDate::LastMonthOfYear(int year) const
{
return (IsLeapYear(year) ? 13 : 12);
}
void HebrewDate::FromAbsolute(int absDate)
{
// approximate the year (erring low)
y = (absDate + HebrewEpoch) / 366;
// search forward for the correct year from the guess
while(absDate >= HebrewDate(1,7,y+1))
y++;
// search forward for the month from either Tishrei or Nisan
if(absDate < HebrewDate(1,1,y))
m = 7;
else
m = 1;
while(absDate > HebrewDate(LastDayOfMonth(m,y), m, y))
m++;
// calculate the day by subtraction
d = absDate - HebrewDate(1,m,y) + 1;
}
// Compute the absolute date from a Hebrew date
HebrewDate::operator int() const
{
int dayInYear = d; // Days so far this month.
// Before Tishri, so add days in prior months
// this year before and after Nisan.
if(m < 7)
{
int mon = 7;
while(mon <= (LastMonthOfYear(y)))
{
dayInYear = dayInYear + LastDayOfMonth(mon, y);
mon++;
};
mon = 1;
while(mon < m)
{
dayInYear = dayInYear + LastDayOfMonth(mon, y);
mon++;
}
}
else
{
// Add days in prior months this year
int mon = 7;
while(mon < m)
{
dayInYear = dayInYear + LastDayOfMonth(mon, y);
mon++;
}
}
return (dayInYear + (DaysFromCreation(y) // Days in prior years.
+ HebrewEpoch));// Days elapsed before absolute date 1.
}
string HebrewDate::MonthName(int month,int year) const
{
switch(month)
{
case 1: return "Nisan";
case 2: return "Iyar";
case 3: return "Sivan";
case 4: return "Tammuz";
case 5: return "Av";
case 6: return "Elul";
case 7: return "Tishrei";
case 8: return "Heshvan";
case 9: return "Kislev";
case 10: return "Tevet";
case 11: return "Shvat";
case 12: return IsLeapYear(year) ? "Adar I" : "Adar";
case 13: return "Adar II";
}
return "Invalid month";
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]