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
275 #define JEWISH_SDN_MAX 324542846L /* 12/13/887605, greater value raises interger overflow */
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 */
Tishri1(int metonicYear,long int moladDay,long int moladHalakim)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 */
MoladOfMetonicCycle(int metonicCycle,long int * pMoladDay,long int * pMoladHalakim)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 */
FindTishriMolad(long int inputDay,int * pMetonicCycle,int * pMetonicYear,long int * pMoladDay,long int * pMoladHalakim)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 */
FindStartOfYear(int year,int * pMetonicCycle,int * pMetonicYear,long int * pMoladDay,long int * pMoladHalakim,int * pTishri1)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 */
SdnToJewish(long int sdn,int * pYear,int * pMonth,int * pDay)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
523 if (sdn <= JEWISH_SDN_OFFSET || sdn > JEWISH_SDN_MAX) {
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 */
JewishToSdn(int year,int month,int day)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 */
765