Re: Hebrew date conversion code - ignore if you're not interested



This site appears to have a lot of information that would be
useful to folks working on this project:

	http://emr.cs.uiuc.edu/home/reingold/calendar-book/index.shtml

There is Java code that can be downloaded.  Unfortunately, it
isn't GPL.  You might try contacting the authors to see about
getting unlimited rights for including algorithms they've developed
and porting them into the GnomeCal and the PIM.


Russell Steinthal wrote:
> 
> // 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";
> }
> 
> --
>         FAQ: Frequently-Asked Questions at http://www.gnome.org/gnomefaq
>          To unsubscribe: mail calendar-list-request@gnome.org with
>                        "unsubscribe" as the Subject.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]