Back to index

php5  5.3.10
jewish.c
Go to the documentation of this file.
00001 /* $selId: jewish.c,v 2.0 1995/10/24 01:13:06 lees Exp $
00002  * Copyright 1993-1995, Scott E. Lee, all rights reserved.
00003  * Permission granted to use, copy, modify, distribute and sell so long as
00004  * the above copyright and this permission statement are retained in all
00005  * copies.  THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
00006  */
00007 
00008 /**************************************************************************
00009  *
00010  * These are the externally visible components of this file:
00011  *
00012  *     void
00013  *     SdnToJewish(
00014  *         long int sdn,
00015  *         int *pYear,
00016  *         int *pMonth,
00017  *         int *pDay);
00018  *
00019  * Convert a SDN to a Jewish calendar date.  If the input SDN is before the
00020  * first day of year 1, the three output values will all be set to zero,
00021  * otherwise *pYear will be > 0; *pMonth will be in the range 1 to 13
00022  * inclusive; *pDay will be in the range 1 to 30 inclusive.  Note that Adar
00023  * II is assigned the month number 7 and Elul is always 13.
00024  *
00025  *     long int
00026  *     JewishToSdn(
00027  *         int year,
00028  *         int month,
00029  *         int day);
00030  *
00031  * Convert a Jewish calendar date to a SDN.  Zero is returned when the
00032  * input date is detected as invalid or out of the supported range.  The
00033  * return value will be > 0 for all valid, supported dates, but there are
00034  * some invalid dates that will return a positive value.  To verify that a
00035  * date is valid, convert it to SDN and then back and compare with the
00036  * original.
00037  *
00038  *     char *JewishMonthName[14];
00039  *
00040  * Convert a Jewish month number (1 to 13) to the name of the Jewish month
00041  * (null terminated).  An index of zero will return a zero length string.
00042  *
00043  * VALID RANGE
00044  *
00045  *     Although this software can handle dates all the way back to the year
00046  *     1 (3761 B.C.), such use may not be meaningful.
00047  *
00048  *     The Jewish calendar has been in use for several thousand years, but
00049  *     in the early days there was no formula to determine the start of a
00050  *     month.  A new month was started when the new moon was first
00051  *     observed.
00052  *
00053  *     It is not clear when the current rule based calendar replaced the
00054  *     observation based calendar.  According to the book "Jewish Calendar
00055  *     Mystery Dispelled" by George Zinberg, the patriarch Hillel II
00056  *     published these rules in 358 A.D.  But, according to The
00057  *     Encyclopedia Judaica, Hillel II may have only published the 19 year
00058  *     rule for determining the occurrence of leap years.
00059  *
00060  *     I have yet to find a specific date when the current set of rules
00061  *     were known to be in use.
00062  *
00063  * CALENDAR OVERVIEW
00064  *
00065  *     The Jewish calendar is based on lunar as well as solar cycles.  A
00066  *     month always starts on or near a new moon and has either 29 or 30
00067  *     days (a lunar cycle is about 29 1/2 days).  Twelve of these
00068  *     alternating 29-30 day months gives a year of 354 days, which is
00069  *     about 11 1/4 days short of a solar year.
00070  *
00071  *     Since a month is defined to be a lunar cycle (new moon to new moon),
00072  *     this 11 1/4 day difference cannot be overcome by adding days to a
00073  *     month as with the Gregorian calendar, so an entire month is
00074  *     periodically added to the year, making some years 13 months long.
00075  *
00076  *     For astronomical as well as ceremonial reasons, the start of a new
00077  *     year may be delayed until a day or two after the new moon causing
00078  *     years to vary in length.  Leap years can be from 383 to 385 days and
00079  *     common years can be from 353 to 355 days.  These are the months of
00080  *     the year and their possible lengths:
00081  *
00082  *                       COMMON YEAR          LEAP YEAR
00083  *          1 Tishri    30   30   30         30   30   30
00084  *          2 Heshvan   29   29   30         29   29   30 (variable)
00085  *          3 Kislev    29   30   30         29   30   30 (variable)
00086  *          4 Tevet     29   29   29         29   29   29
00087  *          5 Shevat    30   30   30         30   30   30
00088  *          6 Adar I    29   29   29         30   30   30 (variable)
00089  *          7 Adar II   --   --   --         29   29   29 (optional)
00090  *          8 Nisan     30   30   30         30   30   30
00091  *          9 Iyyar     29   29   29         29   29   29
00092  *         10 Sivan     30   30   30         30   30   30
00093  *         11 Tammuz    29   29   29         29   29   29
00094  *         12 Av        30   30   30         30   30   30
00095  *         13 Elul      29   29   29         29   29   29
00096  *                     ---  ---  ---        ---  ---  ---
00097  *                     353  354  355        383  384  385
00098  *
00099  *     Note that the month names and other words that appear in this file
00100  *     have multiple possible spellings in the Roman character set.  I have
00101  *     chosen to use the spellings found in the Encyclopedia Judaica.
00102  *
00103  *     Adar II, the month added for leap years, is sometimes referred to as
00104  *     the 13th month, but I have chosen to assign it the number 7 to keep
00105  *     the months in chronological order.  This may not be consistent with
00106  *     other numbering schemes.
00107  *
00108  *     Leap years occur in a fixed pattern of 19 years called the metonic
00109  *     cycle.  The 3rd, 6th, 8th, 11th, 14th, 17th and 19th years of this
00110  *     cycle are leap years.  The first metonic cycle starts with Jewish
00111  *     year 1, or 3761/60 B.C.  This is believed to be the year of
00112  *     creation.
00113  *
00114  *     To construct the calendar for a year, you must first find the length
00115  *     of the year by determining the first day of the year (Tishri 1, or
00116  *     Rosh Ha-Shanah) and the first day of the following year.  This
00117  *     selects one of the six possible month length configurations listed
00118  *     above.
00119  *
00120  *     Finding the first day of the year is the most difficult part.
00121  *     Finding the date and time of the new moon (or molad) is the first
00122  *     step.  For this purpose, the lunar cycle is assumed to be 29 days 12
00123  *     hours and 793 halakim.  A halakim is 1/1080th of an hour or 3 1/3
00124  *     seconds.  (This assumed value is only about 1/2 second less than the
00125  *     value used by modern astronomers -- not bad for a number that was
00126  *     determined so long ago.)  The first molad of year 1 occurred on
00127  *     Sunday at 11:20:11 P.M.  This would actually be Monday, because the
00128  *     Jewish day is considered to begin at sunset.
00129  *
00130  *     Since sunset varies, the day is assumed to begin at 6:00 P.M.  for
00131  *     calendar calculation purposes.  So, the first molad was 5 hours 793
00132  *     halakim after the start of Tishri 1, 0001 (which was Monday
00133  *     September 7, 4761 B.C. by the Gregorian calendar).  All subsequent
00134  *     molads can be calculated from this starting point by adding the
00135  *     length of a lunar cycle.
00136  *
00137  *     Once the molad that starts a year is determined the actual start of
00138  *     the year (Tishri 1) can be determined.  Tishri 1 will be the day of
00139  *     the molad unless it is delayed by one of the following four rules
00140  *     (called dehiyyot).  Each rule can delay the start of the year by one
00141  *     day, and since rule #1 can combine with one of the other rules, it
00142  *     can be delayed as much as two days.
00143  *
00144  *         1.  Tishri 1 must never be Sunday, Wednesday or Friday.  (This
00145  *             is largely to prevent certain holidays from occurring on the
00146  *             day before or after the Sabbath.)
00147  *
00148  *         2.  If the molad occurs on or after noon, Tishri 1 must be
00149  *             delayed.
00150  *
00151  *         3.  If it is a common (not leap) year and the molad occurs on
00152  *             Tuesday at or after 3:11:20 A.M., Tishri 1 must be delayed.
00153  *
00154  *         4.  If it is the year following a leap year and the molad occurs
00155  *             on Monday at or after 9:32:43 and 1/3 sec, Tishri 1 must be
00156  *             delayed.
00157  *
00158  * GLOSSARY
00159  *
00160  *     dehiyyot         The set of 4 rules that determine when the new year
00161  *                      starts relative to the molad.
00162  *
00163  *     halakim          1/1080th of an hour or 3 1/3 seconds.
00164  *
00165  *     lunar cycle      The period of time between mean conjunctions of the
00166  *                      sun and moon (new moon to new moon).  This is
00167  *                      assumed to be 29 days 12 hours and 793 halakim for
00168  *                      calendar purposes.
00169  *
00170  *     metonic cycle    A 19 year cycle which determines which years are
00171  *                      leap years and which are common years.  The 3rd,
00172  *                      6th, 8th, 11th, 14th, 17th and 19th years of this
00173  *                      cycle are leap years.
00174  *
00175  *     molad            The date and time of the mean conjunction of the
00176  *                      sun and moon (new moon).  This is the approximate
00177  *                      beginning of a month.
00178  *
00179  *     Rosh Ha-Shanah   The first day of the Jewish year (Tishri 1).
00180  *
00181  *     Tishri           The first month of the Jewish year.
00182  *
00183  * ALGORITHMS
00184  *
00185  *     SERIAL DAY NUMBER TO JEWISH DATE
00186  *
00187  *     The simplest approach would be to use the rules stated above to find
00188  *     the molad of Tishri before and after the given day number.  Then use
00189  *     the molads to find Tishri 1 of the current and following years.
00190  *     From this the length of the year can be determined and thus the
00191  *     length of each month.  But this method is used as a last resort.
00192  *
00193  *     The first 59 days of the year are the same regardless of the length
00194  *     of the year.  As a result, only the day number of the start of the
00195  *     year is required.
00196  *
00197  *     Similarly, the last 6 months do not change from year to year.  And
00198  *     since it can be determined whether the year is a leap year by simple
00199  *     division, the lengths of Adar I and II can be easily calculated.  In
00200  *     fact, all dates after the 3rd month are consistent from year to year
00201  *     (once it is known whether it is a leap year).
00202  *
00203  *     This means that if the given day number falls in the 3rd month or on
00204  *     the 30th day of the 2nd month the length of the year must be found,
00205  *     but in no other case.
00206  *
00207  *     So, the approach used is to take the given day number and round it
00208  *     to the closest molad of Tishri (first new moon of the year).  The
00209  *     rounding is not really to the *closest* molad, but is such that if
00210  *     the day number is before the middle of the 3rd month the molad at
00211  *     the start of the year is found, otherwise the molad at the end of
00212  *     the year is found.
00213  *
00214  *     Only if the day number is actually found to be in the ambiguous
00215  *     period of 29 to 31 days is the other molad calculated.
00216  *
00217  *     JEWISH DATE TO SERIAL DAY NUMBER
00218  *
00219  *     The year number is used to find which 19 year metonic cycle contains
00220  *     the date and which year within the cycle (this is a division and
00221  *     modulus).  This also determines whether it is a leap year.
00222  *
00223  *     If the month is 1 or 2, the calculation is simple addition to the
00224  *     first of the year.
00225  *
00226  *     If the month is 8 (Nisan) or greater, the calculation is simple
00227  *     subtraction from beginning of the following year.
00228  *
00229  *     If the month is 4 to 7, it is considered whether it is a leap year
00230  *     and then simple subtraction from the beginning of the following year
00231  *     is used.
00232  *
00233  *     Only if it is the 3rd month is both the start and end of the year
00234  *     required.
00235  *
00236  * TESTING
00237  *
00238  *     This algorithm has been tested in two ways.  First, 510 dates from a
00239  *     table in "Jewish Calendar Mystery Dispelled" were calculated and
00240  *     compared to the table.  Second, the calculation algorithm described
00241  *     in "Jewish Calendar Mystery Dispelled" was coded and used to verify
00242  *     all dates from the year 1 (3761 B.C.) to the year 13760 (10000
00243  *     A.D.).
00244  *
00245  *     The source code of the verification program is included in this
00246  *     package.
00247  *
00248  * REFERENCES
00249  *
00250  *     The Encyclopedia Judaica, the entry for "Calendar"
00251  *
00252  *     The Jewish Encyclopedia
00253  *
00254  *     Jewish Calendar Mystery Dispelled by George Zinberg, Vantage Press,
00255  *     1963
00256  *
00257  *     The Comprehensive Hebrew Calendar by Arthur Spier, Behrman House
00258  *
00259  *     The Book of Calendars [note that this work contains many typos]
00260  *
00261  **************************************************************************/
00262 
00263 #if defined(PHP_WIN32) && _MSC_VER >= 1200
00264 #pragma setlocale("english")
00265 #endif
00266 
00267 #include "sdncal.h"
00268 
00269 #define HALAKIM_PER_HOUR 1080
00270 #define HALAKIM_PER_DAY 25920
00271 #define HALAKIM_PER_LUNAR_CYCLE ((29 * HALAKIM_PER_DAY) + 13753)
00272 #define HALAKIM_PER_METONIC_CYCLE (HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7))
00273 
00274 #define JEWISH_SDN_OFFSET 347997
00275 #define NEW_MOON_OF_CREATION 31524
00276 
00277 #define SUNDAY    0
00278 #define MONDAY    1
00279 #define TUESDAY   2
00280 #define WEDNESDAY 3
00281 #define THURSDAY  4
00282 #define FRIDAY    5
00283 #define SATURDAY  6
00284 
00285 #define NOON (18 * HALAKIM_PER_HOUR)
00286 #define AM3_11_20 ((9 * HALAKIM_PER_HOUR) + 204)
00287 #define AM9_32_43 ((15 * HALAKIM_PER_HOUR) + 589)
00288 
00289 static int monthsPerYear[19] =
00290 {
00291 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13
00292 };
00293 
00294 static int yearOffset[19] =
00295 {
00296        0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123,
00297        136, 148, 160, 173, 185, 197, 210, 222
00298 };
00299 
00300 char *JewishMonthName[14] =
00301 {
00302        "",
00303        "Tishri",
00304        "Heshvan",
00305        "Kislev",
00306        "Tevet",
00307        "Shevat",
00308        "AdarI",
00309        "AdarII",
00310        "Nisan",
00311        "Iyyar",
00312        "Sivan",
00313        "Tammuz",
00314        "Av",
00315        "Elul"
00316 };
00317 
00318 char *JewishMonthHebName[14] =
00319 {
00320        "",
00321        "תשרי",
00322        "חשון",
00323        "כסלו",
00324        "טבת",
00325        "שבט",
00326        "אדר",
00327        "'אדר ב",
00328        "ניסן",
00329        "אייר",
00330        "סיון",
00331        "תמוז",
00332        "אב",
00333        "אלול"
00334 };
00335 
00336 /************************************************************************
00337  * Given the year within the 19 year metonic cycle and the time of a molad
00338  * (new moon) which starts that year, this routine will calculate what day
00339  * will be the actual start of the year (Tishri 1 or Rosh Ha-Shanah).  This
00340  * first day of the year will be the day of the molad unless one of 4 rules
00341  * (called dehiyyot) delays it.  These 4 rules can delay the start of the
00342  * year by as much as 2 days.
00343  */
00344 static long int Tishri1(
00345                                              int metonicYear,
00346                                              long int moladDay,
00347                                              long int moladHalakim)
00348 {
00349        long int tishri1;
00350        int dow;
00351        int leapYear;
00352        int lastWasLeapYear;
00353 
00354        tishri1 = moladDay;
00355        dow = tishri1 % 7;
00356        leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7
00357               || metonicYear == 10 || metonicYear == 13 || metonicYear == 16
00358               || metonicYear == 18;
00359        lastWasLeapYear = metonicYear == 3 || metonicYear == 6
00360               || metonicYear == 8 || metonicYear == 11 || metonicYear == 14
00361               || metonicYear == 17 || metonicYear == 0;
00362 
00363        /* Apply rules 2, 3 and 4. */
00364        if ((moladHalakim >= NOON) ||
00365               ((!leapYear) && dow == TUESDAY && moladHalakim >= AM3_11_20) ||
00366               (lastWasLeapYear && dow == MONDAY && moladHalakim >= AM9_32_43)) {
00367               tishri1++;
00368               dow++;
00369               if (dow == 7) {
00370                      dow = 0;
00371               }
00372        }
00373        /* Apply rule 1 after the others because it can cause an additional
00374         * delay of one day. */
00375        if (dow == WEDNESDAY || dow == FRIDAY || dow == SUNDAY) {
00376               tishri1++;
00377        }
00378        return (tishri1);
00379 }
00380 
00381 /************************************************************************
00382  * Given a metonic cycle number, calculate the date and time of the molad
00383  * (new moon) that starts that cycle.  Since the length of a metonic cycle
00384  * is a constant, this is a simple calculation, except that it requires an
00385  * intermediate value which is bigger that 32 bits.  Because this
00386  * intermediate value only needs 36 to 37 bits and the other numbers are
00387  * constants, the process has been reduced to just a few steps.
00388  */
00389 static void MoladOfMetonicCycle(
00390                                                            int metonicCycle,
00391                                                            long int *pMoladDay,
00392                                                            long int *pMoladHalakim)
00393 {
00394        register unsigned long int r1, r2, d1, d2;
00395 
00396        /* Start with the time of the first molad after creation. */
00397        r1 = NEW_MOON_OF_CREATION;
00398 
00399        /* Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE.  The upper 32
00400         * bits of the result will be in r2 and the lower 16 bits will be
00401         * in r1. */
00402        r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF);
00403        r2 = r1 >> 16;
00404        r2 += metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF);
00405 
00406        /* Calculate r2r1 / HALAKIM_PER_DAY.  The remainder will be in r1, the
00407         * upper 16 bits of the quotient will be in d2 and the lower 16 bits
00408         * will be in d1. */
00409        d2 = r2 / HALAKIM_PER_DAY;
00410        r2 -= d2 * HALAKIM_PER_DAY;
00411        r1 = (r2 << 16) | (r1 & 0xFFFF);
00412        d1 = r1 / HALAKIM_PER_DAY;
00413        r1 -= d1 * HALAKIM_PER_DAY;
00414 
00415        *pMoladDay = (d2 << 16) | d1;
00416        *pMoladHalakim = r1;
00417 }
00418 
00419 /************************************************************************
00420  * Given a day number, find the molad of Tishri (the new moon at the start
00421  * of a year) which is closest to that day number.  It's not really the
00422  * *closest* molad that we want here.  If the input day is in the first two
00423  * months, we want the molad at the start of the year.  If the input day is
00424  * in the fourth to last months, we want the molad at the end of the year.
00425  * If the input day is in the third month, it doesn't matter which molad is
00426  * returned, because both will be required.  This type of "rounding" allows
00427  * us to avoid calculating the length of the year in most cases.
00428  */
00429 static void FindTishriMolad(
00430                                                     long int inputDay,
00431                                                     int *pMetonicCycle,
00432                                                     int *pMetonicYear,
00433                                                     long int *pMoladDay,
00434                                                     long int *pMoladHalakim)
00435 {
00436        long int moladDay;
00437        long int moladHalakim;
00438        int metonicCycle;
00439        int metonicYear;
00440 
00441        /* Estimate the metonic cycle number.  Note that this may be an under
00442         * estimate because there are 6939.6896 days in a metonic cycle not
00443         * 6940, but it will never be an over estimate.  The loop below will
00444         * correct for any error in this estimate. */
00445        metonicCycle = (inputDay + 310) / 6940;
00446 
00447        /* Calculate the time of the starting molad for this metonic cycle. */
00448        MoladOfMetonicCycle(metonicCycle, &moladDay, &moladHalakim);
00449 
00450        /* If the above was an under estimate, increment the cycle number until
00451         * the correct one is found.  For modern dates this loop is about 98.6%
00452         * likely to not execute, even once, because the above estimate is
00453         * really quite close. */
00454        while (moladDay < inputDay - 6940 + 310) {
00455               metonicCycle++;
00456               moladHalakim += HALAKIM_PER_METONIC_CYCLE;
00457               moladDay += moladHalakim / HALAKIM_PER_DAY;
00458               moladHalakim = moladHalakim % HALAKIM_PER_DAY;
00459        }
00460 
00461        /* Find the molad of Tishri closest to this date. */
00462        for (metonicYear = 0; metonicYear < 18; metonicYear++) {
00463               if (moladDay > inputDay - 74) {
00464                      break;
00465               }
00466               moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
00467               moladDay += moladHalakim / HALAKIM_PER_DAY;
00468               moladHalakim = moladHalakim % HALAKIM_PER_DAY;
00469        }
00470 
00471        *pMetonicCycle = metonicCycle;
00472        *pMetonicYear = metonicYear;
00473        *pMoladDay = moladDay;
00474        *pMoladHalakim = moladHalakim;
00475 }
00476 
00477 /************************************************************************
00478  * Given a year, find the number of the first day of that year and the date
00479  * and time of the starting molad.
00480  */
00481 static void FindStartOfYear(
00482                                                     int year,
00483                                                     int *pMetonicCycle,
00484                                                     int *pMetonicYear,
00485                                                     long int *pMoladDay,
00486                                                     long int *pMoladHalakim,
00487                                                     int *pTishri1)
00488 {
00489        *pMetonicCycle = (year - 1) / 19;
00490        *pMetonicYear = (year - 1) % 19;
00491        MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim);
00492 
00493        *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear];
00494        *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY;
00495        *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY;
00496 
00497        *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim);
00498 }
00499 
00500 /************************************************************************
00501  * Given a serial day number (SDN), find the corresponding year, month and
00502  * day in the Jewish calendar.  The three output values will always be
00503  * modified.  If the input SDN is before the first day of year 1, they will
00504  * all be set to zero, otherwise *pYear will be > 0; *pMonth will be in the
00505  * range 1 to 13 inclusive; *pDay will be in the range 1 to 30 inclusive.
00506  */
00507 void SdnToJewish(
00508                                    long int sdn,
00509                                    int *pYear,
00510                                    int *pMonth,
00511                                    int *pDay)
00512 {
00513        long int inputDay;
00514        long int day;
00515        long int halakim;
00516        int metonicCycle;
00517        int metonicYear;
00518        int tishri1;
00519        int tishri1After;
00520        int yearLength;
00521 
00522        if (sdn <= JEWISH_SDN_OFFSET) {
00523               *pYear = 0;
00524               *pMonth = 0;
00525               *pDay = 0;
00526               return;
00527        }
00528        inputDay = sdn - JEWISH_SDN_OFFSET;
00529 
00530        FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim);
00531        tishri1 = Tishri1(metonicYear, day, halakim);
00532 
00533        if (inputDay >= tishri1) {
00534               /* It found Tishri 1 at the start of the year. */
00535               *pYear = metonicCycle * 19 + metonicYear + 1;
00536               if (inputDay < tishri1 + 59) {
00537                      if (inputDay < tishri1 + 30) {
00538                             *pMonth = 1;
00539                             *pDay = inputDay - tishri1 + 1;
00540                      } else {
00541                             *pMonth = 2;
00542                             *pDay = inputDay - tishri1 - 29;
00543                      }
00544                      return;
00545               }
00546               /* We need the length of the year to figure this out, so find
00547                * Tishri 1 of the next year. */
00548               halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
00549               day += halakim / HALAKIM_PER_DAY;
00550               halakim = halakim % HALAKIM_PER_DAY;
00551               tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim);
00552        } else {
00553               /* It found Tishri 1 at the end of the year. */
00554               *pYear = metonicCycle * 19 + metonicYear;
00555               if (inputDay >= tishri1 - 177) {
00556                      /* It is one of the last 6 months of the year. */
00557                      if (inputDay > tishri1 - 30) {
00558                             *pMonth = 13;
00559                             *pDay = inputDay - tishri1 + 30;
00560                      } else if (inputDay > tishri1 - 60) {
00561                             *pMonth = 12;
00562                             *pDay = inputDay - tishri1 + 60;
00563                      } else if (inputDay > tishri1 - 89) {
00564                             *pMonth = 11;
00565                             *pDay = inputDay - tishri1 + 89;
00566                      } else if (inputDay > tishri1 - 119) {
00567                             *pMonth = 10;
00568                             *pDay = inputDay - tishri1 + 119;
00569                      } else if (inputDay > tishri1 - 148) {
00570                             *pMonth = 9;
00571                             *pDay = inputDay - tishri1 + 148;
00572                      } else {
00573                             *pMonth = 8;
00574                             *pDay = inputDay - tishri1 + 178;
00575                      }
00576                      return;
00577               } else {
00578                      if (monthsPerYear[(*pYear - 1) % 19] == 13) {
00579                             *pMonth = 7;
00580                             *pDay = inputDay - tishri1 + 207;
00581                             if (*pDay > 0)
00582                                    return;
00583                             (*pMonth)--;
00584                             (*pDay) += 30;
00585                             if (*pDay > 0)
00586                                    return;
00587                             (*pMonth)--;
00588                             (*pDay) += 30;
00589                      } else {
00590                             *pMonth = 6;
00591                             *pDay = inputDay - tishri1 + 207;
00592                             if (*pDay > 0)
00593                                    return;
00594                             (*pMonth)--;
00595                             (*pDay) += 30;
00596                      }
00597                      if (*pDay > 0)
00598                             return;
00599                      (*pMonth)--;
00600                      (*pDay) += 29;
00601                      if (*pDay > 0)
00602                             return;
00603 
00604                      /* We need the length of the year to figure this out, so find
00605                       * Tishri 1 of this year. */
00606                      tishri1After = tishri1;
00607                      FindTishriMolad(day - 365,
00608                                                  &metonicCycle, &metonicYear, &day, &halakim);
00609                      tishri1 = Tishri1(metonicYear, day, halakim);
00610               }
00611        }
00612 
00613        yearLength = tishri1After - tishri1;
00614        day = inputDay - tishri1 - 29;
00615        if (yearLength == 355 || yearLength == 385) {
00616               /* Heshvan has 30 days */
00617               if (day <= 30) {
00618                      *pMonth = 2;
00619                      *pDay = day;
00620                      return;
00621               }
00622               day -= 30;
00623        } else {
00624               /* Heshvan has 29 days */
00625               if (day <= 29) {
00626                      *pMonth = 2;
00627                      *pDay = day;
00628                      return;
00629               }
00630               day -= 29;
00631        }
00632 
00633        /* It has to be Kislev. */
00634        *pMonth = 3;
00635        *pDay = day;
00636 }
00637 
00638 /************************************************************************
00639  * Given a year, month and day in the Jewish calendar, find the
00640  * corresponding serial day number (SDN).  Zero is returned when the input
00641  * date is detected as invalid.  The return value will be > 0 for all valid
00642  * dates, but there are some invalid dates that will return a positive
00643  * value.  To verify that a date is valid, convert it to SDN and then back
00644  * and compare with the original.
00645  */
00646 long int JewishToSdn(
00647                                           int year,
00648                                           int month,
00649                                           int day)
00650 {
00651        long int sdn;
00652        int metonicCycle;
00653        int metonicYear;
00654        int tishri1;
00655        int tishri1After;
00656        long int moladDay;
00657        long int moladHalakim;
00658        int yearLength;
00659        int lengthOfAdarIAndII;
00660 
00661        if (year <= 0 || day <= 0 || day > 30) {
00662               return (0);
00663        }
00664        switch (month) {
00665               case 1:
00666               case 2:
00667                      /* It is Tishri or Heshvan - don't need the year length. */
00668                      FindStartOfYear(year, &metonicCycle, &metonicYear,
00669                                                  &moladDay, &moladHalakim, &tishri1);
00670                      if (month == 1) {
00671                             sdn = tishri1 + day - 1;
00672                      } else {
00673                             sdn = tishri1 + day + 29;
00674                      }
00675                      break;
00676 
00677               case 3:
00678                      /* It is Kislev - must find the year length. */
00679 
00680                      /* Find the start of the year. */
00681                      FindStartOfYear(year, &metonicCycle, &metonicYear,
00682                                                  &moladDay, &moladHalakim, &tishri1);
00683 
00684                      /* Find the end of the year. */
00685                      moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
00686                      moladDay += moladHalakim / HALAKIM_PER_DAY;
00687                      moladHalakim = moladHalakim % HALAKIM_PER_DAY;
00688                      tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim);
00689 
00690                      yearLength = tishri1After - tishri1;
00691 
00692                      if (yearLength == 355 || yearLength == 385) {
00693                             sdn = tishri1 + day + 59;
00694                      } else {
00695                             sdn = tishri1 + day + 58;
00696                      }
00697                      break;
00698 
00699               case 4:
00700               case 5:
00701               case 6:
00702                      /* It is Tevet, Shevat or Adar I - don't need the year length. */
00703 
00704                      FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
00705                                                  &moladDay, &moladHalakim, &tishri1After);
00706 
00707                      if (monthsPerYear[(year - 1) % 19] == 12) {
00708                             lengthOfAdarIAndII = 29;
00709                      } else {
00710                             lengthOfAdarIAndII = 59;
00711                      }
00712 
00713                      if (month == 4) {
00714                             sdn = tishri1After + day - lengthOfAdarIAndII - 237;
00715                      } else if (month == 5) {
00716                             sdn = tishri1After + day - lengthOfAdarIAndII - 208;
00717                      } else {
00718                             sdn = tishri1After + day - lengthOfAdarIAndII - 178;
00719                      }
00720                      break;
00721 
00722               default:
00723                      /* It is Adar II or later - don't need the year length. */
00724                      FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
00725                                                  &moladDay, &moladHalakim, &tishri1After);
00726 
00727                      switch (month) {
00728                             case 7:
00729                                    sdn = tishri1After + day - 207;
00730                                    break;
00731                             case 8:
00732                                    sdn = tishri1After + day - 178;
00733                                    break;
00734                             case 9:
00735                                    sdn = tishri1After + day - 148;
00736                                    break;
00737                             case 10:
00738                                    sdn = tishri1After + day - 119;
00739                                    break;
00740                             case 11:
00741                                    sdn = tishri1After + day - 89;
00742                                    break;
00743                             case 12:
00744                                    sdn = tishri1After + day - 60;
00745                                    break;
00746                             case 13:
00747                                    sdn = tishri1After + day - 30;
00748                                    break;
00749                             default:
00750                                    return (0);
00751                      }
00752        }
00753        return (sdn + JEWISH_SDN_OFFSET);
00754 }
00755 
00756 /*
00757  * Local variables:
00758  * tab-width: 4
00759  * c-basic-offset: 4
00760  * End:
00761  * vim600: sw=4 ts=4 fdm=marker
00762  * vim<600: sw=4 ts=4
00763  */