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