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 NEW_MOON_OF_CREATION 31524
276 :
277 : #define SUNDAY 0
278 : #define MONDAY 1
279 : #define TUESDAY 2
280 : #define WEDNESDAY 3
281 : #define THURSDAY 4
282 : #define FRIDAY 5
283 : #define SATURDAY 6
284 :
285 : #define NOON (18 * HALAKIM_PER_HOUR)
286 : #define AM3_11_20 ((9 * HALAKIM_PER_HOUR) + 204)
287 : #define AM9_32_43 ((15 * HALAKIM_PER_HOUR) + 589)
288 :
289 : static int monthsPerYear[19] =
290 : {
291 : 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13
292 : };
293 :
294 : static int yearOffset[19] =
295 : {
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 : "",
303 : "Tishri",
304 : "Heshvan",
305 : "Kislev",
306 : "Tevet",
307 : "Shevat",
308 : "AdarI",
309 : "AdarII",
310 : "Nisan",
311 : "Iyyar",
312 : "Sivan",
313 : "Tammuz",
314 : "Av",
315 : "Elul"
316 : };
317 :
318 : char *JewishMonthHebName[14] =
319 : {
320 : "",
321 : "תשרי",
322 : "חשון",
323 : "כסלו",
324 : "טבת",
325 : "שבט",
326 : "אדר",
327 : "'אדר ב",
328 : "ניסן",
329 : "אייר",
330 : "סיון",
331 : "תמוז",
332 : "אב",
333 : "אלול"
334 : };
335 :
336 : /************************************************************************
337 : * Given the year within the 19 year metonic cycle and the time of a molad
338 : * (new moon) which starts that year, this routine will calculate what day
339 : * will be the actual start of the year (Tishri 1 or Rosh Ha-Shanah). This
340 : * first day of the year will be the day of the molad unless one of 4 rules
341 : * (called dehiyyot) delays it. These 4 rules can delay the start of the
342 : * year by as much as 2 days.
343 : */
344 : static long int Tishri1(
345 : int metonicYear,
346 : long int moladDay,
347 : long int moladHalakim)
348 59 : {
349 : long int tishri1;
350 : int dow;
351 : int leapYear;
352 : int lastWasLeapYear;
353 :
354 59 : tishri1 = moladDay;
355 59 : dow = tishri1 % 7;
356 59 : leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7
357 : || metonicYear == 10 || metonicYear == 13 || metonicYear == 16
358 : || metonicYear == 18;
359 59 : lastWasLeapYear = metonicYear == 3 || metonicYear == 6
360 : || metonicYear == 8 || metonicYear == 11 || metonicYear == 14
361 : || metonicYear == 17 || metonicYear == 0;
362 :
363 : /* Apply rules 2, 3 and 4. */
364 59 : if ((moladHalakim >= NOON) ||
365 : ((!leapYear) && dow == TUESDAY && moladHalakim >= AM3_11_20) ||
366 : (lastWasLeapYear && dow == MONDAY && moladHalakim >= AM9_32_43)) {
367 17 : tishri1++;
368 17 : dow++;
369 17 : if (dow == 7) {
370 0 : dow = 0;
371 : }
372 : }
373 : /* Apply rule 1 after the others because it can cause an additional
374 : * delay of one day. */
375 59 : if (dow == WEDNESDAY || dow == FRIDAY || dow == SUNDAY) {
376 8 : tishri1++;
377 : }
378 59 : return (tishri1);
379 : }
380 :
381 : /************************************************************************
382 : * Given a metonic cycle number, calculate the date and time of the molad
383 : * (new moon) that starts that cycle. Since the length of a metonic cycle
384 : * is a constant, this is a simple calculation, except that it requires an
385 : * intermediate value which is bigger that 32 bits. Because this
386 : * intermediate value only needs 36 to 37 bits and the other numbers are
387 : * constants, the process has been reduced to just a few steps.
388 : */
389 : static void MoladOfMetonicCycle(
390 : int metonicCycle,
391 : long int *pMoladDay,
392 : long int *pMoladHalakim)
393 59 : {
394 : register unsigned long int r1, r2, d1, d2;
395 :
396 : /* Start with the time of the first molad after creation. */
397 59 : r1 = NEW_MOON_OF_CREATION;
398 :
399 : /* Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32
400 : * bits of the result will be in r2 and the lower 16 bits will be
401 : * in r1. */
402 59 : r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF);
403 59 : r2 = r1 >> 16;
404 59 : r2 += metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF);
405 :
406 : /* Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1, the
407 : * upper 16 bits of the quotient will be in d2 and the lower 16 bits
408 : * will be in d1. */
409 59 : d2 = r2 / HALAKIM_PER_DAY;
410 59 : r2 -= d2 * HALAKIM_PER_DAY;
411 59 : r1 = (r2 << 16) | (r1 & 0xFFFF);
412 59 : d1 = r1 / HALAKIM_PER_DAY;
413 59 : r1 -= d1 * HALAKIM_PER_DAY;
414 :
415 59 : *pMoladDay = (d2 << 16) | d1;
416 59 : *pMoladHalakim = r1;
417 59 : }
418 :
419 : /************************************************************************
420 : * Given a day number, find the molad of Tishri (the new moon at the start
421 : * of a year) which is closest to that day number. It's not really the
422 : * *closest* molad that we want here. If the input day is in the first two
423 : * months, we want the molad at the start of the year. If the input day is
424 : * in the fourth to last months, we want the molad at the end of the year.
425 : * If the input day is in the third month, it doesn't matter which molad is
426 : * returned, because both will be required. This type of "rounding" allows
427 : * us to avoid calculating the length of the year in most cases.
428 : */
429 : static void FindTishriMolad(
430 : long int inputDay,
431 : int *pMetonicCycle,
432 : int *pMetonicYear,
433 : long int *pMoladDay,
434 : long int *pMoladHalakim)
435 56 : {
436 : long int moladDay;
437 : long int moladHalakim;
438 : int metonicCycle;
439 : int metonicYear;
440 :
441 : /* Estimate the metonic cycle number. Note that this may be an under
442 : * estimate because there are 6939.6896 days in a metonic cycle not
443 : * 6940, but it will never be an over estimate. The loop below will
444 : * correct for any error in this estimate. */
445 56 : metonicCycle = (inputDay + 310) / 6940;
446 :
447 : /* Calculate the time of the starting molad for this metonic cycle. */
448 56 : MoladOfMetonicCycle(metonicCycle, &moladDay, &moladHalakim);
449 :
450 : /* If the above was an under estimate, increment the cycle number until
451 : * the correct one is found. For modern dates this loop is about 98.6%
452 : * likely to not execute, even once, because the above estimate is
453 : * really quite close. */
454 112 : while (moladDay < inputDay - 6940 + 310) {
455 0 : metonicCycle++;
456 0 : moladHalakim += HALAKIM_PER_METONIC_CYCLE;
457 0 : moladDay += moladHalakim / HALAKIM_PER_DAY;
458 0 : moladHalakim = moladHalakim % HALAKIM_PER_DAY;
459 : }
460 :
461 : /* Find the molad of Tishri closest to this date. */
462 513 : for (metonicYear = 0; metonicYear < 18; metonicYear++) {
463 513 : if (moladDay > inputDay - 74) {
464 56 : break;
465 : }
466 457 : moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
467 457 : moladDay += moladHalakim / HALAKIM_PER_DAY;
468 457 : moladHalakim = moladHalakim % HALAKIM_PER_DAY;
469 : }
470 :
471 56 : *pMetonicCycle = metonicCycle;
472 56 : *pMetonicYear = metonicYear;
473 56 : *pMoladDay = moladDay;
474 56 : *pMoladHalakim = moladHalakim;
475 56 : }
476 :
477 : /************************************************************************
478 : * Given a year, find the number of the first day of that year and the date
479 : * and time of the starting molad.
480 : */
481 : static void FindStartOfYear(
482 : int year,
483 : int *pMetonicCycle,
484 : int *pMetonicYear,
485 : long int *pMoladDay,
486 : long int *pMoladHalakim,
487 : int *pTishri1)
488 3 : {
489 3 : *pMetonicCycle = (year - 1) / 19;
490 3 : *pMetonicYear = (year - 1) % 19;
491 3 : MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim);
492 :
493 3 : *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear];
494 3 : *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY;
495 3 : *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY;
496 :
497 3 : *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim);
498 3 : }
499 :
500 : /************************************************************************
501 : * Given a serial day number (SDN), find the corresponding year, month and
502 : * day in the Jewish calendar. The three output values will always be
503 : * modified. If the input SDN is before the first day of year 1, they will
504 : * all be set to zero, otherwise *pYear will be > 0; *pMonth will be in the
505 : * range 1 to 13 inclusive; *pDay will be in the range 1 to 30 inclusive.
506 : */
507 : void SdnToJewish(
508 : long int sdn,
509 : int *pYear,
510 : int *pMonth,
511 : int *pDay)
512 54 : {
513 : long int inputDay;
514 : long int day;
515 : long int halakim;
516 : int metonicCycle;
517 : int metonicYear;
518 : int tishri1;
519 : int tishri1After;
520 : int yearLength;
521 :
522 54 : if (sdn <= JEWISH_SDN_OFFSET) {
523 1 : *pYear = 0;
524 1 : *pMonth = 0;
525 1 : *pDay = 0;
526 1 : return;
527 : }
528 53 : inputDay = sdn - JEWISH_SDN_OFFSET;
529 :
530 53 : FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim);
531 53 : tishri1 = Tishri1(metonicYear, day, halakim);
532 :
533 53 : if (inputDay >= tishri1) {
534 : /* It found Tishri 1 at the start of the year. */
535 17 : *pYear = metonicCycle * 19 + metonicYear + 1;
536 17 : if (inputDay < tishri1 + 59) {
537 17 : if (inputDay < tishri1 + 30) {
538 4 : *pMonth = 1;
539 4 : *pDay = inputDay - tishri1 + 1;
540 : } else {
541 13 : *pMonth = 2;
542 13 : *pDay = inputDay - tishri1 - 29;
543 : }
544 17 : return;
545 : }
546 : /* We need the length of the year to figure this out, so find
547 : * Tishri 1 of the next year. */
548 0 : halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
549 0 : day += halakim / HALAKIM_PER_DAY;
550 0 : halakim = halakim % HALAKIM_PER_DAY;
551 0 : tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim);
552 : } else {
553 : /* It found Tishri 1 at the end of the year. */
554 36 : *pYear = metonicCycle * 19 + metonicYear;
555 36 : if (inputDay >= tishri1 - 177) {
556 : /* It is one of the last 6 months of the year. */
557 21 : if (inputDay > tishri1 - 30) {
558 4 : *pMonth = 13;
559 4 : *pDay = inputDay - tishri1 + 30;
560 17 : } else if (inputDay > tishri1 - 60) {
561 3 : *pMonth = 12;
562 3 : *pDay = inputDay - tishri1 + 60;
563 14 : } else if (inputDay > tishri1 - 89) {
564 4 : *pMonth = 11;
565 4 : *pDay = inputDay - tishri1 + 89;
566 10 : } else if (inputDay > tishri1 - 119) {
567 3 : *pMonth = 10;
568 3 : *pDay = inputDay - tishri1 + 119;
569 7 : } else if (inputDay > tishri1 - 148) {
570 3 : *pMonth = 9;
571 3 : *pDay = inputDay - tishri1 + 148;
572 : } else {
573 4 : *pMonth = 8;
574 4 : *pDay = inputDay - tishri1 + 178;
575 : }
576 21 : return;
577 : } else {
578 15 : if (monthsPerYear[(*pYear - 1) % 19] == 13) {
579 6 : *pMonth = 7;
580 6 : *pDay = inputDay - tishri1 + 207;
581 6 : if (*pDay > 0)
582 1 : return;
583 5 : (*pMonth)--;
584 5 : (*pDay) += 30;
585 5 : if (*pDay > 0)
586 1 : return;
587 4 : (*pMonth)--;
588 4 : (*pDay) += 30;
589 : } else {
590 9 : *pMonth = 6;
591 9 : *pDay = inputDay - tishri1 + 207;
592 9 : if (*pDay > 0)
593 2 : return;
594 7 : (*pMonth)--;
595 7 : (*pDay) += 30;
596 : }
597 11 : if (*pDay > 0)
598 4 : return;
599 7 : (*pMonth)--;
600 7 : (*pDay) += 29;
601 7 : if (*pDay > 0)
602 4 : return;
603 :
604 : /* We need the length of the year to figure this out, so find
605 : * Tishri 1 of this year. */
606 3 : tishri1After = tishri1;
607 3 : FindTishriMolad(day - 365,
608 : &metonicCycle, &metonicYear, &day, &halakim);
609 3 : tishri1 = Tishri1(metonicYear, day, halakim);
610 : }
611 : }
612 :
613 3 : yearLength = tishri1After - tishri1;
614 3 : day = inputDay - tishri1 - 29;
615 4 : if (yearLength == 355 || yearLength == 385) {
616 : /* Heshvan has 30 days */
617 1 : if (day <= 30) {
618 0 : *pMonth = 2;
619 0 : *pDay = day;
620 0 : return;
621 : }
622 1 : day -= 30;
623 : } else {
624 : /* Heshvan has 29 days */
625 2 : if (day <= 29) {
626 0 : *pMonth = 2;
627 0 : *pDay = day;
628 0 : return;
629 : }
630 2 : day -= 29;
631 : }
632 :
633 : /* It has to be Kislev. */
634 3 : *pMonth = 3;
635 3 : *pDay = day;
636 : }
637 :
638 : /************************************************************************
639 : * Given a year, month and day in the Jewish calendar, find the
640 : * corresponding serial day number (SDN). Zero is returned when the input
641 : * date is detected as invalid. The return value will be > 0 for all valid
642 : * dates, but there are some invalid dates that will return a positive
643 : * value. To verify that a date is valid, convert it to SDN and then back
644 : * and compare with the original.
645 : */
646 : long int JewishToSdn(
647 : int year,
648 : int month,
649 : int day)
650 5 : {
651 : long int sdn;
652 : int metonicCycle;
653 : int metonicYear;
654 : int tishri1;
655 : int tishri1After;
656 : long int moladDay;
657 : long int moladHalakim;
658 : int yearLength;
659 : int lengthOfAdarIAndII;
660 :
661 5 : if (year <= 0 || day <= 0 || day > 30) {
662 2 : return (0);
663 : }
664 3 : switch (month) {
665 : case 1:
666 : case 2:
667 : /* It is Tishri or Heshvan - don't need the year length. */
668 2 : FindStartOfYear(year, &metonicCycle, &metonicYear,
669 : &moladDay, &moladHalakim, &tishri1);
670 2 : if (month == 1) {
671 1 : sdn = tishri1 + day - 1;
672 : } else {
673 1 : sdn = tishri1 + day + 29;
674 : }
675 2 : break;
676 :
677 : case 3:
678 : /* It is Kislev - must find the year length. */
679 :
680 : /* Find the start of the year. */
681 0 : FindStartOfYear(year, &metonicCycle, &metonicYear,
682 : &moladDay, &moladHalakim, &tishri1);
683 :
684 : /* Find the end of the year. */
685 0 : moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
686 0 : moladDay += moladHalakim / HALAKIM_PER_DAY;
687 0 : moladHalakim = moladHalakim % HALAKIM_PER_DAY;
688 0 : tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim);
689 :
690 0 : yearLength = tishri1After - tishri1;
691 :
692 0 : if (yearLength == 355 || yearLength == 385) {
693 0 : sdn = tishri1 + day + 59;
694 : } else {
695 0 : sdn = tishri1 + day + 58;
696 : }
697 0 : break;
698 :
699 : case 4:
700 : case 5:
701 : case 6:
702 : /* It is Tevet, Shevat or Adar I - don't need the year length. */
703 :
704 0 : FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
705 : &moladDay, &moladHalakim, &tishri1After);
706 :
707 0 : if (monthsPerYear[(year - 1) % 19] == 12) {
708 0 : lengthOfAdarIAndII = 29;
709 : } else {
710 0 : lengthOfAdarIAndII = 59;
711 : }
712 :
713 0 : if (month == 4) {
714 0 : sdn = tishri1After + day - lengthOfAdarIAndII - 237;
715 0 : } else if (month == 5) {
716 0 : sdn = tishri1After + day - lengthOfAdarIAndII - 208;
717 : } else {
718 0 : sdn = tishri1After + day - lengthOfAdarIAndII - 178;
719 : }
720 0 : break;
721 :
722 : default:
723 : /* It is Adar II or later - don't need the year length. */
724 1 : FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
725 : &moladDay, &moladHalakim, &tishri1After);
726 :
727 1 : switch (month) {
728 : case 7:
729 0 : sdn = tishri1After + day - 207;
730 0 : break;
731 : case 8:
732 1 : sdn = tishri1After + day - 178;
733 1 : break;
734 : case 9:
735 0 : sdn = tishri1After + day - 148;
736 0 : break;
737 : case 10:
738 0 : sdn = tishri1After + day - 119;
739 0 : break;
740 : case 11:
741 0 : sdn = tishri1After + day - 89;
742 0 : break;
743 : case 12:
744 0 : sdn = tishri1After + day - 60;
745 0 : break;
746 : case 13:
747 0 : sdn = tishri1After + day - 30;
748 0 : break;
749 : default:
750 0 : return (0);
751 : }
752 : }
753 3 : return (sdn + JEWISH_SDN_OFFSET);
754 : }
755 :
756 : /*
757 : * Local variables:
758 : * tab-width: 4
759 : * c-basic-offset: 4
760 : * End:
761 : * vim600: sw=4 ts=4 fdm=marker
762 : * vim<600: sw=4 ts=4
763 : */
|