Removed support for testing with dmalloc (valgrind is better...).
[gedcom-parse.git] / gedcom / calendar / jewish.c
1 /* This file is taken from http://www.genealogy.org/~scottlee/
2    Only this initial comment has been added.  The next comment
3    gives the original copyright notice.
4 */
5
6
7 /* $selId: jewish.c,v 2.0 1995/10/24 01:13:06 lees Exp $
8  * Copyright 1993-1995, Scott E. Lee, all rights reserved.
9  * Permission granted to use, copy, modify, distribute and sell so long as
10  * the above copyright and this permission statement are retained in all
11  * copies.  THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
12  */
13
14 /**************************************************************************
15  *
16  * These are the externally visible components of this file:
17  *
18  *     void
19  *     SdnToJewish(
20  *         long int sdn,
21  *         int *pYear,
22  *         int *pMonth,
23  *         int *pDay);
24  *
25  * Convert a SDN to a Jewish calendar date.  If the input SDN is before the
26  * first day of year 1, the three output values will all be set to zero,
27  * otherwise *pYear will be > 0; *pMonth will be in the range 1 to 13
28  * inclusive; *pDay will be in the range 1 to 30 inclusive.  Note that Adar
29  * II is assigned the month number 7 and Elul is always 13.
30  *
31  *     long int
32  *     JewishToSdn(
33  *         int year,
34  *         int month,
35  *         int day);
36  *
37  * Convert a Jewish calendar date to a SDN.  Zero is returned when the
38  * input date is detected as invalid or out of the supported range.  The
39  * return value will be > 0 for all valid, supported dates, but there are
40  * some invalid dates that will return a positive value.  To verify that a
41  * date is valid, convert it to SDN and then back and compare with the
42  * original.
43  *
44  *     char *JewishMonthName[14];
45  *
46  * Convert a Jewish month number (1 to 13) to the name of the Jewish month
47  * (null terminated).  An index of zero will return a zero length string.
48  *
49  * VALID RANGE
50  *
51  *     Although this software can handle dates all the way back to the year
52  *     1 (3761 B.C.), such use may not be meaningful.
53  *
54  *     The Jewish calendar has been in use for several thousand years, but
55  *     in the early days there was no formula to determine the start of a
56  *     month.  A new month was started when the new moon was first
57  *     observed.
58  *
59  *     It is not clear when the current rule based calendar replaced the
60  *     observation based calendar.  According to the book "Jewish Calendar
61  *     Mystery Dispelled" by George Zinberg, the patriarch Hillel II
62  *     published these rules in 358 A.D.  But, according to The
63  *     Encyclopedia Judaica, Hillel II may have only published the 19 year
64  *     rule for determining the occurrence of leap years.
65  *
66  *     I have yet to find a specific date when the current set of rules
67  *     were known to be in use.
68  *
69  * CALENDAR OVERVIEW
70  *
71  *     The Jewish calendar is based on lunar as well as solar cycles.  A
72  *     month always starts on or near a new moon and has either 29 or 30
73  *     days (a lunar cycle is about 29 1/2 days).  Twelve of these
74  *     alternating 29-30 day months gives a year of 354 days, which is
75  *     about 11 1/4 days short of a solar year.
76  *
77  *     Since a month is defined to be a lunar cycle (new moon to new moon),
78  *     this 11 1/4 day difference cannot be overcome by adding days to a
79  *     month as with the Gregorian calendar, so an entire month is
80  *     periodically added to the year, making some years 13 months long.
81  *
82  *     For astronomical as well as ceremonial reasons, the start of a new
83  *     year may be delayed until a day or two after the new moon causing
84  *     years to vary in length.  Leap years can be from 383 to 385 days and
85  *     common years can be from 353 to 355 days.  These are the months of
86  *     the year and their possible lengths:
87  *
88  *                       COMMON YEAR          LEAP YEAR
89  *          1 Tishri    30   30   30         30   30   30
90  *          2 Heshvan   29   29   30         29   29   30 (variable)
91  *          3 Kislev    29   30   30         29   30   30 (variable)
92  *          4 Tevet     29   29   29         29   29   29
93  *          5 Shevat    30   30   30         30   30   30
94  *          6 Adar I    29   29   29         30   30   30 (variable)
95  *          7 Adar II   --   --   --         29   29   29 (optional)
96  *          8 Nisan     30   30   30         30   30   30
97  *          9 Iyyar     29   29   29         29   29   29
98  *         10 Sivan     30   30   30         30   30   30
99  *         11 Tammuz    29   29   29         29   29   29
100  *         12 Av        30   30   30         30   30   30
101  *         13 Elul      29   29   29         29   29   29
102  *                     ---  ---  ---        ---  ---  ---
103  *                     353  354  355        383  384  385
104  *
105  *     Note that the month names and other words that appear in this file
106  *     have multiple possible spellings in the Roman character set.  I have
107  *     chosen to use the spellings found in the Encyclopedia Judaica.
108  *
109  *     Adar II, the month added for leap years, is sometimes referred to as
110  *     the 13th month, but I have chosen to assign it the number 7 to keep
111  *     the months in chronological order.  This may not be consistent with
112  *     other numbering schemes.
113  *
114  *     Leap years occur in a fixed pattern of 19 years called the metonic
115  *     cycle.  The 3rd, 6th, 8th, 11th, 14th, 17th and 19th years of this
116  *     cycle are leap years.  The first metonic cycle starts with Jewish
117  *     year 1, or 3761/60 B.C.  This is believed to be the year of
118  *     creation.
119  *
120  *     To construct the calendar for a year, you must first find the length
121  *     of the year by determining the first day of the year (Tishri 1, or
122  *     Rosh Ha-Shanah) and the first day of the following year.  This
123  *     selects one of the six possible month length configurations listed
124  *     above.
125  *
126  *     Finding the first day of the year is the most difficult part.
127  *     Finding the date and time of the new moon (or molad) is the first
128  *     step.  For this purpose, the lunar cycle is assumed to be 29 days 12
129  *     hours and 793 halakim.  A halakim is 1/1080th of an hour or 3 1/3
130  *     seconds.  (This assumed value is only about 1/2 second less than the
131  *     value used by modern astronomers -- not bad for a number that was
132  *     determined so long ago.)  The first molad of year 1 occurred on
133  *     Sunday at 11:20:11 P.M.  This would actually be Monday, because the
134  *     Jewish day is considered to begin at sunset.
135  *
136  *     Since sunset varies, the day is assumed to begin at 6:00 P.M.  for
137  *     calendar calculation purposes.  So, the first molad was 5 hours 793
138  *     halakim after the start of Tishri 1, 0001 (which was Monday
139  *     September 7, 4761 B.C. by the Gregorian calendar).  All subsequent
140  *     molads can be calculated from this starting point by adding the
141  *     length of a lunar cycle.
142  *
143  *     Once the molad that starts a year is determined the actual start of
144  *     the year (Tishri 1) can be determined.  Tishri 1 will be the day of
145  *     the molad unless it is delayed by one of the following four rules
146  *     (called dehiyyot).  Each rule can delay the start of the year by one
147  *     day, and since rule #1 can combine with one of the other rules, it
148  *     can be delayed as much as two days.
149  *
150  *         1.  Tishri 1 must never be Sunday, Wednesday or Friday.  (This
151  *             is largely to prevent certain holidays from occurring on the
152  *             day before or after the Sabbath.)
153  *
154  *         2.  If the molad occurs on or after noon, Tishri 1 must be
155  *             delayed.
156  *
157  *         3.  If it is a common (not leap) year and the molad occurs on
158  *             Tuesday at or after 3:11:20 A.M., Tishri 1 must be delayed.
159  *
160  *         4.  If it is the year following a leap year and the molad occurs
161  *             on Monday at or after 9:32:43 and 1/3 sec, Tishri 1 must be
162  *             delayed.
163  *
164  * GLOSSARY
165  *
166  *     dehiyyot         The set of 4 rules that determine when the new year
167  *                      starts relative to the molad.
168  *
169  *     halakim          1/1080th of an hour or 3 1/3 seconds.
170  *
171  *     lunar cycle      The period of time between mean conjunctions of the
172  *                      sun and moon (new moon to new moon).  This is
173  *                      assumed to be 29 days 12 hours and 793 halakim for
174  *                      calendar purposes.
175  *
176  *     metonic cycle    A 19 year cycle which determines which years are
177  *                      leap years and which are common years.  The 3rd,
178  *                      6th, 8th, 11th, 14th, 17th and 19th years of this
179  *                      cycle are leap years.
180  *
181  *     molad            The date and time of the mean conjunction of the
182  *                      sun and moon (new moon).  This is the approximate
183  *                      beginning of a month.
184  *
185  *     Rosh Ha-Shanah   The first day of the Jewish year (Tishri 1).
186  *
187  *     Tishri           The first month of the Jewish year.
188  *
189  * ALGORITHMS
190  *
191  *     SERIAL DAY NUMBER TO JEWISH DATE
192  *
193  *     The simplest approach would be to use the rules stated above to find
194  *     the molad of Tishri before and after the given day number.  Then use
195  *     the molads to find Tishri 1 of the current and following years.
196  *     From this the length of the year can be determined and thus the
197  *     length of each month.  But this method is used as a last resort.
198  *
199  *     The first 59 days of the year are the same regardless of the length
200  *     of the year.  As a result, only the day number of the start of the
201  *     year is required.
202  *
203  *     Similarly, the last 6 months do not change from year to year.  And
204  *     since it can be determined whether the year is a leap year by simple
205  *     division, the lengths of Adar I and II can be easily calculated.  In
206  *     fact, all dates after the 3rd month are consistent from year to year
207  *     (once it is known whether it is a leap year).
208  *
209  *     This means that if the given day number falls in the 3rd month or on
210  *     the 30th day of the 2nd month the length of the year must be found,
211  *     but in no other case.
212  *
213  *     So, the approach used is to take the given day number and round it
214  *     to the closest molad of Tishri (first new moon of the year).  The
215  *     rounding is not really to the *closest* molad, but is such that if
216  *     the day number is before the middle of the 3rd month the molad at
217  *     the start of the year is found, otherwise the molad at the end of
218  *     the year is found.
219  *
220  *     Only if the day number is actually found to be in the ambiguous
221  *     period of 29 to 31 days is the other molad calculated.
222  *
223  *     JEWISH DATE TO SERIAL DAY NUMBER
224  *
225  *     The year number is used to find which 19 year metonic cycle contains
226  *     the date and which year within the cycle (this is a division and
227  *     modulus).  This also determines whether it is a leap year.
228  *
229  *     If the month is 1 or 2, the calculation is simple addition to the
230  *     first of the year.
231  *
232  *     If the month is 8 (Nisan) or greater, the calculation is simple
233  *     subtraction from beginning of the following year.
234  *
235  *     If the month is 4 to 7, it is considered whether it is a leap year
236  *     and then simple subtraction from the beginning of the following year
237  *     is used.
238  *
239  *     Only if it is the 3rd month is both the start and end of the year
240  *     required.
241  *
242  * TESTING
243  *
244  *     This algorithm has been tested in two ways.  First, 510 dates from a
245  *     table in "Jewish Calendar Mystery Dispelled" were calculated and
246  *     compared to the table.  Second, the calculation algorithm described
247  *     in "Jewish Calendar Mystery Dispelled" was coded and used to verify
248  *     all dates from the year 1 (3761 B.C.) to the year 13760 (10000
249  *     A.D.).
250  *
251  *     The source code of the verification program is included in this
252  *     package.
253  *
254  * REFERENCES
255  *
256  *     The Encyclopedia Judaica, the entry for "Calendar"
257  *
258  *     The Jewish Encyclopedia
259  *
260  *     Jewish Calendar Mystery Dispelled by George Zinberg, Vantage Press,
261  *     1963
262  *
263  *     The Comprehensive Hebrew Calendar by Arthur Spier, Behrman House
264  *
265  *     The Book of Calendars [note that this work contains many typos]
266  *
267  **************************************************************************/
268
269 #include "sdncal.h"
270
271 #define HALAKIM_PER_HOUR 1080
272 #define HALAKIM_PER_DAY 25920
273 #define HALAKIM_PER_LUNAR_CYCLE ((29 * HALAKIM_PER_DAY) + 13753)
274 #define HALAKIM_PER_METONIC_CYCLE (HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7))
275
276 #define SDN_OFFSET 347997
277 #define NEW_MOON_OF_CREATION 31524
278
279 #define SUNDAY    0
280 #define MONDAY    1
281 #define TUESDAY   2
282 #define WEDNESDAY 3
283 #define THURSDAY  4
284 #define FRIDAY    5
285 #define SATURDAY  6
286
287 #define NOON (18 * HALAKIM_PER_HOUR)
288 #define AM3_11_20 ((9 * HALAKIM_PER_HOUR) + 204)
289 #define AM9_32_43 ((15 * HALAKIM_PER_HOUR) + 589)
290
291 static int monthsPerYear[19] = {
292     12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13
293 };
294
295 static int yearOffset[19] = {
296     0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123,
297     136, 148, 160, 173, 185, 197, 210, 222
298 };
299
300 char *JewishMonthName[14] = {
301     "",
302     "Tishri",
303     "Heshvan",
304     "Kislev",
305     "Tevet",
306     "Shevat",
307     "AdarI",
308     "AdarII",
309     "Nisan",
310     "Iyyar",
311     "Sivan",
312     "Tammuz",
313     "Av",
314     "Elul"
315 };
316
317 /************************************************************************
318  * Given the year within the 19 year metonic cycle and the time of a molad
319  * (new moon) which starts that year, this routine will calculate what day
320  * will be the actual start of the year (Tishri 1 or Rosh Ha-Shanah).  This
321  * first day of the year will be the day of the molad unless one of 4 rules
322  * (called dehiyyot) delays it.  These 4 rules can delay the start of the
323  * year by as much as 2 days.
324  */
325 static long int
326 Tishri1(
327     int      metonicYear,
328     long int moladDay,
329     long int moladHalakim)
330 {
331     long int tishri1;
332     int dow;
333     int leapYear;
334     int lastWasLeapYear;
335
336     tishri1 = moladDay;
337     dow = tishri1 % 7;
338     leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7
339         || metonicYear == 10 || metonicYear == 13 || metonicYear == 16
340         || metonicYear == 18;
341     lastWasLeapYear = metonicYear == 3 || metonicYear == 6
342         || metonicYear == 8 || metonicYear == 11 || metonicYear == 14
343         || metonicYear == 17 || metonicYear == 0;
344
345     /* Apply rules 2, 3 and 4. */
346     if ((moladHalakim >= NOON) ||
347         ((!leapYear) && dow == TUESDAY && moladHalakim >= AM3_11_20) ||
348         (lastWasLeapYear && dow == MONDAY && moladHalakim >= AM9_32_43))
349     {
350         tishri1++;
351         dow++;
352         if (dow == 7) {
353             dow = 0;
354         }
355     }
356
357     /* Apply rule 1 after the others because it can cause an additional
358      * delay of one day. */
359     if (dow == WEDNESDAY || dow == FRIDAY || dow == SUNDAY) {
360         tishri1++;
361     }
362
363     return(tishri1);
364 }
365
366 /************************************************************************
367  * Given a metonic cycle number, calculate the date and time of the molad
368  * (new moon) that starts that cycle.  Since the length of a metonic cycle
369  * is a constant, this is a simple calculation, except that it requires an
370  * intermediate value which is bigger that 32 bits.  Because this
371  * intermediate value only needs 36 to 37 bits and the other numbers are
372  * constants, the process has been reduced to just a few steps.
373  */
374 static void
375 MoladOfMetonicCycle(
376     int       metonicCycle,
377     long int *pMoladDay,
378     long int *pMoladHalakim)
379 {
380     register unsigned long int r1, r2, d1, d2;
381
382     /* Start with the time of the first molad after creation. */
383     r1 = NEW_MOON_OF_CREATION;
384
385     /* Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE.  The upper 32
386      * bits of the result will be in r2 and the lower 16 bits will be
387      * in r1. */
388     r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF);
389     r2 = r1 >> 16;
390     r2 += metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF);
391
392     /* Calculate r2r1 / HALAKIM_PER_DAY.  The remainder will be in r1, the
393      * upper 16 bits of the quotient will be in d2 and the lower 16 bits
394      * will be in d1. */
395     d2 = r2 / HALAKIM_PER_DAY;
396     r2 -= d2 * HALAKIM_PER_DAY;
397     r1 = (r2 << 16) | (r1 & 0xFFFF);
398     d1 = r1 / HALAKIM_PER_DAY;
399     r1 -= d1 * HALAKIM_PER_DAY;
400
401     *pMoladDay = (d2 << 16) | d1;
402     *pMoladHalakim = r1;
403 }
404
405 /************************************************************************
406  * Given a day number, find the molad of Tishri (the new moon at the start
407  * of a year) which is closest to that day number.  It's not really the
408  * *closest* molad that we want here.  If the input day is in the first two
409  * months, we want the molad at the start of the year.  If the input day is
410  * in the fourth to last months, we want the molad at the end of the year.
411  * If the input day is in the third month, it doesn't matter which molad is
412  * returned, because both will be required.  This type of "rounding" allows
413  * us to avoid calculating the length of the year in most cases.
414  */
415 static void
416 FindTishriMolad(
417     long int inputDay,
418     int *pMetonicCycle,
419     int *pMetonicYear,
420     long int *pMoladDay,
421     long int *pMoladHalakim)
422 {
423     long int moladDay;
424     long int moladHalakim;
425     int metonicCycle;
426     int metonicYear;
427
428     /* Estimate the metonic cycle number.  Note that this may be an under
429      * estimate because there are 6939.6896 days in a metonic cycle not
430      * 6940, but it will never be an over estimate.  The loop below will
431      * correct for any error in this estimate. */
432     metonicCycle = (inputDay + 310) / 6940;
433
434     /* Calculate the time of the starting molad for this metonic cycle. */
435     MoladOfMetonicCycle(metonicCycle, &moladDay, &moladHalakim);
436
437     /* If the above was an under estimate, increment the cycle number until
438      * the correct one is found.  For modern dates this loop is about 98.6%
439      * likely to not execute, even once, because the above estimate is
440      * really quite close. */
441     while (moladDay < inputDay - 6940 + 310) {
442         metonicCycle++;
443         moladHalakim += HALAKIM_PER_METONIC_CYCLE;
444         moladDay += moladHalakim / HALAKIM_PER_DAY;
445         moladHalakim = moladHalakim % HALAKIM_PER_DAY;
446     }
447
448     /* Find the molad of Tishri closest to this date. */
449     for (metonicYear = 0; metonicYear < 18; metonicYear++) {
450         if (moladDay > inputDay - 74) {
451             break;
452         }
453         moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
454         moladDay += moladHalakim / HALAKIM_PER_DAY;
455         moladHalakim = moladHalakim % HALAKIM_PER_DAY;
456     }
457
458     *pMetonicCycle = metonicCycle;
459     *pMetonicYear = metonicYear;
460     *pMoladDay = moladDay;
461     *pMoladHalakim = moladHalakim;
462 }
463
464 /************************************************************************
465  * Given a year, find the number of the first day of that year and the date
466  * and time of the starting molad.
467  */
468 static void
469 FindStartOfYear(
470     int       year,
471     int      *pMetonicCycle,
472     int      *pMetonicYear,
473     long int *pMoladDay,
474     long int *pMoladHalakim,
475     int      *pTishri1)
476 {
477     *pMetonicCycle = (year - 1) / 19;
478     *pMetonicYear = (year - 1) % 19;
479     MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim);
480
481     *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear];
482     *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY;
483     *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY;
484
485     *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim);
486 }
487
488 /************************************************************************
489  * Given a serial day number (SDN), find the corresponding year, month and
490  * day in the Jewish calendar.  The three output values will always be
491  * modified.  If the input SDN is before the first day of year 1, they will
492  * all be set to zero, otherwise *pYear will be > 0; *pMonth will be in the
493  * range 1 to 13 inclusive; *pDay will be in the range 1 to 30 inclusive.
494  */
495 void
496 SdnToJewish(
497     long int sdn,
498     int *pYear,
499     int *pMonth,
500     int *pDay)
501 {
502     long int inputDay;
503     long int day;
504     long int halakim;
505     int metonicCycle;
506     int metonicYear;
507     int tishri1;
508     int tishri1After;
509     int yearLength;
510
511     if (sdn <= SDN_OFFSET) {
512         *pYear = 0;
513         *pMonth = 0;
514         *pDay = 0;
515         return;
516     }
517     inputDay = sdn - SDN_OFFSET;
518
519     FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim);
520     tishri1 = Tishri1(metonicYear, day, halakim);
521
522     if (inputDay >= tishri1) {
523         /* It found Tishri 1 at the start of the year. */
524         *pYear = metonicCycle * 19 + metonicYear + 1;
525         if (inputDay < tishri1 + 59) {
526             if (inputDay < tishri1 + 30) {
527                 *pMonth = 1;
528                 *pDay = inputDay - tishri1 + 1;
529             } else {
530                 *pMonth = 2;
531                 *pDay = inputDay - tishri1 - 29;
532             }
533             return;
534         }
535
536         /* We need the length of the year to figure this out, so find
537          * Tishri 1 of the next year. */
538         halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
539         day += halakim / HALAKIM_PER_DAY;
540         halakim = halakim % HALAKIM_PER_DAY;
541         tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim);
542     } else {
543         /* It found Tishri 1 at the end of the year. */
544         *pYear = metonicCycle * 19 + metonicYear;
545         if (inputDay >= tishri1 - 177) {
546             /* It is one of the last 6 months of the year. */
547             if (inputDay > tishri1 - 30) {
548                 *pMonth = 13;
549                 *pDay = inputDay - tishri1 + 30;
550             } else if (inputDay > tishri1 - 60) {
551                 *pMonth = 12;
552                 *pDay = inputDay - tishri1 + 60;
553             } else if (inputDay > tishri1 - 89) {
554                 *pMonth = 11;
555                 *pDay = inputDay - tishri1 + 89;
556             } else if (inputDay > tishri1 - 119) {
557                 *pMonth = 10;
558                 *pDay = inputDay - tishri1 + 119;
559             } else if (inputDay > tishri1 - 148) {
560                 *pMonth = 9;
561                 *pDay = inputDay - tishri1 + 148;
562             } else {
563                 *pMonth = 8;
564                 *pDay = inputDay - tishri1 + 178;
565             }
566             return;
567         } else {
568             if (monthsPerYear[(*pYear - 1) % 19] == 13) {
569                 *pMonth = 7;
570                 *pDay = inputDay - tishri1 + 207;
571                 if (*pDay > 0) return;
572                 (*pMonth)--;
573                 (*pDay) += 30;
574                 if (*pDay > 0) return;
575                 (*pMonth)--;
576                 (*pDay) += 30;
577             } else {
578                 *pMonth = 6;
579                 *pDay = inputDay - tishri1 + 207;
580                 if (*pDay > 0) return;
581                 (*pMonth)--;
582                 (*pDay) += 30;
583             }
584             if (*pDay > 0) return;
585             (*pMonth)--;
586             (*pDay) += 29;
587             if (*pDay > 0) return;
588
589             /* We need the length of the year to figure this out, so find
590              * Tishri 1 of this year. */
591             tishri1After = tishri1;
592             FindTishriMolad(day - 365,
593                 &metonicCycle, &metonicYear, &day, &halakim);
594             tishri1 = Tishri1(metonicYear, day, halakim);
595         }
596     }
597
598     yearLength = tishri1After - tishri1;
599     day = inputDay - tishri1 - 29;
600     if (yearLength == 355 || yearLength == 385) {
601         /* Heshvan has 30 days */
602         if (day <= 30) {
603             *pMonth = 2;
604             *pDay = day;
605             return;
606         }
607         day -= 30;
608     } else {
609         /* Heshvan has 29 days */
610         if (day <= 29) {
611             *pMonth = 2;
612             *pDay = day;
613             return;
614         }
615         day -= 29;
616     }
617
618     /* It has to be Kislev. */
619     *pMonth = 3;
620     *pDay = day;
621 }
622
623 /************************************************************************
624  * Given a year, month and day in the Jewish calendar, find the
625  * corresponding serial day number (SDN).  Zero is returned when the input
626  * date is detected as invalid.  The return value will be > 0 for all valid
627  * dates, but there are some invalid dates that will return a positive
628  * value.  To verify that a date is valid, convert it to SDN and then back
629  * and compare with the original.
630  */
631 long int
632 JewishToSdn(
633     int year,
634     int month,
635     int day)
636 {
637     long int sdn;
638     int      metonicCycle;
639     int      metonicYear;
640     int      tishri1;
641     int      tishri1After;
642     long int moladDay;
643     long int moladHalakim;
644     int      yearLength;
645     int      lengthOfAdarIAndII;
646
647     if (year <= 0 || day <= 0 || day > 30) {
648         return(0);
649     }
650
651     switch (month) {
652     case 1:
653     case 2:
654         /* It is Tishri or Heshvan - don't need the year length. */
655         FindStartOfYear(year, &metonicCycle, &metonicYear,
656             &moladDay, &moladHalakim, &tishri1);
657         if (month == 1) {
658             sdn = tishri1 + day - 1;
659         } else {
660             sdn = tishri1 + day + 29;
661         }
662         break;
663
664     case 3:
665         /* It is Kislev - must find the year length. */
666
667         /* Find the start of the year. */
668         FindStartOfYear(year, &metonicCycle, &metonicYear,
669             &moladDay, &moladHalakim, &tishri1);
670
671         /* Find the end of the year. */
672         moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
673         moladDay += moladHalakim / HALAKIM_PER_DAY;
674         moladHalakim = moladHalakim % HALAKIM_PER_DAY;
675         tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim);
676
677         yearLength = tishri1After - tishri1;
678
679         if (yearLength == 355 || yearLength == 385) {
680             sdn = tishri1 + day + 59;
681         } else {
682             sdn = tishri1 + day + 58;
683         }
684         break;
685
686     case 4:
687     case 5:
688     case 6:
689         /* It is Tevet, Shevat or Adar I - don't need the year length. */
690
691         FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
692             &moladDay, &moladHalakim, &tishri1After);
693
694         if (monthsPerYear[(year - 1) % 19] == 12) {
695             lengthOfAdarIAndII = 29;
696         } else {
697             lengthOfAdarIAndII = 59;
698         }
699
700         if (month == 4) {
701             sdn = tishri1After + day - lengthOfAdarIAndII - 237;
702         } else if (month == 5) {
703             sdn = tishri1After + day - lengthOfAdarIAndII - 208;
704         } else {
705             sdn = tishri1After + day - lengthOfAdarIAndII - 178;
706         }
707         break;
708
709     default:
710         /* It is Adar II or later - don't need the year length. */
711         FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
712             &moladDay, &moladHalakim, &tishri1After);
713
714         switch (month) {
715         case  7:
716             sdn = tishri1After + day - 207;
717             break;
718         case  8:
719             sdn = tishri1After + day - 178;
720             break;
721         case  9:
722             sdn = tishri1After + day - 148;
723             break;
724         case 10:
725             sdn = tishri1After + day - 119;
726             break;
727         case 11:
728             sdn = tishri1After + day - 89;
729             break;
730         case 12:
731             sdn = tishri1After + day - 60;
732             break;
733         case 13:
734             sdn = tishri1After + day - 30;
735             break;
736         default:
737             return(0);
738         }
739     }
740     return(sdn + SDN_OFFSET);
741 }