Return to jewish.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / calendar |
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 ! 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: { ! 349: long int tishri1; ! 350: int dow; ! 351: int leapYear; ! 352: int lastWasLeapYear; ! 353: ! 354: tishri1 = moladDay; ! 355: dow = tishri1 % 7; ! 356: leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7 ! 357: || metonicYear == 10 || metonicYear == 13 || metonicYear == 16 ! 358: || metonicYear == 18; ! 359: 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: if ((moladHalakim >= NOON) || ! 365: ((!leapYear) && dow == TUESDAY && moladHalakim >= AM3_11_20) || ! 366: (lastWasLeapYear && dow == MONDAY && moladHalakim >= AM9_32_43)) { ! 367: tishri1++; ! 368: dow++; ! 369: if (dow == 7) { ! 370: dow = 0; ! 371: } ! 372: } ! 373: /* Apply rule 1 after the others because it can cause an additional ! 374: * delay of one day. */ ! 375: if (dow == WEDNESDAY || dow == FRIDAY || dow == SUNDAY) { ! 376: tishri1++; ! 377: } ! 378: 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: { ! 394: register unsigned long int r1, r2, d1, d2; ! 395: ! 396: /* Start with the time of the first molad after creation. */ ! 397: 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: r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF); ! 403: r2 = r1 >> 16; ! 404: 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: d2 = r2 / HALAKIM_PER_DAY; ! 410: r2 -= d2 * HALAKIM_PER_DAY; ! 411: r1 = (r2 << 16) | (r1 & 0xFFFF); ! 412: d1 = r1 / HALAKIM_PER_DAY; ! 413: r1 -= d1 * HALAKIM_PER_DAY; ! 414: ! 415: *pMoladDay = (d2 << 16) | d1; ! 416: *pMoladHalakim = r1; ! 417: } ! 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: { ! 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: metonicCycle = (inputDay + 310) / 6940; ! 446: ! 447: /* Calculate the time of the starting molad for this metonic cycle. */ ! 448: 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: while (moladDay < inputDay - 6940 + 310) { ! 455: metonicCycle++; ! 456: moladHalakim += HALAKIM_PER_METONIC_CYCLE; ! 457: moladDay += moladHalakim / HALAKIM_PER_DAY; ! 458: moladHalakim = moladHalakim % HALAKIM_PER_DAY; ! 459: } ! 460: ! 461: /* Find the molad of Tishri closest to this date. */ ! 462: for (metonicYear = 0; metonicYear < 18; metonicYear++) { ! 463: if (moladDay > inputDay - 74) { ! 464: break; ! 465: } ! 466: moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; ! 467: moladDay += moladHalakim / HALAKIM_PER_DAY; ! 468: moladHalakim = moladHalakim % HALAKIM_PER_DAY; ! 469: } ! 470: ! 471: *pMetonicCycle = metonicCycle; ! 472: *pMetonicYear = metonicYear; ! 473: *pMoladDay = moladDay; ! 474: *pMoladHalakim = moladHalakim; ! 475: } ! 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: { ! 489: *pMetonicCycle = (year - 1) / 19; ! 490: *pMetonicYear = (year - 1) % 19; ! 491: MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim); ! 492: ! 493: *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear]; ! 494: *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY; ! 495: *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY; ! 496: ! 497: *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim); ! 498: } ! 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: { ! 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: if (sdn <= JEWISH_SDN_OFFSET) { ! 523: *pYear = 0; ! 524: *pMonth = 0; ! 525: *pDay = 0; ! 526: return; ! 527: } ! 528: inputDay = sdn - JEWISH_SDN_OFFSET; ! 529: ! 530: FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim); ! 531: tishri1 = Tishri1(metonicYear, day, halakim); ! 532: ! 533: if (inputDay >= tishri1) { ! 534: /* It found Tishri 1 at the start of the year. */ ! 535: *pYear = metonicCycle * 19 + metonicYear + 1; ! 536: if (inputDay < tishri1 + 59) { ! 537: if (inputDay < tishri1 + 30) { ! 538: *pMonth = 1; ! 539: *pDay = inputDay - tishri1 + 1; ! 540: } else { ! 541: *pMonth = 2; ! 542: *pDay = inputDay - tishri1 - 29; ! 543: } ! 544: return; ! 545: } ! 546: /* We need the length of the year to figure this out, so find ! 547: * Tishri 1 of the next year. */ ! 548: halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; ! 549: day += halakim / HALAKIM_PER_DAY; ! 550: halakim = halakim % HALAKIM_PER_DAY; ! 551: tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim); ! 552: } else { ! 553: /* It found Tishri 1 at the end of the year. */ ! 554: *pYear = metonicCycle * 19 + metonicYear; ! 555: if (inputDay >= tishri1 - 177) { ! 556: /* It is one of the last 6 months of the year. */ ! 557: if (inputDay > tishri1 - 30) { ! 558: *pMonth = 13; ! 559: *pDay = inputDay - tishri1 + 30; ! 560: } else if (inputDay > tishri1 - 60) { ! 561: *pMonth = 12; ! 562: *pDay = inputDay - tishri1 + 60; ! 563: } else if (inputDay > tishri1 - 89) { ! 564: *pMonth = 11; ! 565: *pDay = inputDay - tishri1 + 89; ! 566: } else if (inputDay > tishri1 - 119) { ! 567: *pMonth = 10; ! 568: *pDay = inputDay - tishri1 + 119; ! 569: } else if (inputDay > tishri1 - 148) { ! 570: *pMonth = 9; ! 571: *pDay = inputDay - tishri1 + 148; ! 572: } else { ! 573: *pMonth = 8; ! 574: *pDay = inputDay - tishri1 + 178; ! 575: } ! 576: return; ! 577: } else { ! 578: if (monthsPerYear[(*pYear - 1) % 19] == 13) { ! 579: *pMonth = 7; ! 580: *pDay = inputDay - tishri1 + 207; ! 581: if (*pDay > 0) ! 582: return; ! 583: (*pMonth)--; ! 584: (*pDay) += 30; ! 585: if (*pDay > 0) ! 586: return; ! 587: (*pMonth)--; ! 588: (*pDay) += 30; ! 589: } else { ! 590: *pMonth = 6; ! 591: *pDay = inputDay - tishri1 + 207; ! 592: if (*pDay > 0) ! 593: return; ! 594: (*pMonth)--; ! 595: (*pDay) += 30; ! 596: } ! 597: if (*pDay > 0) ! 598: return; ! 599: (*pMonth)--; ! 600: (*pDay) += 29; ! 601: if (*pDay > 0) ! 602: return; ! 603: ! 604: /* We need the length of the year to figure this out, so find ! 605: * Tishri 1 of this year. */ ! 606: tishri1After = tishri1; ! 607: FindTishriMolad(day - 365, ! 608: &metonicCycle, &metonicYear, &day, &halakim); ! 609: tishri1 = Tishri1(metonicYear, day, halakim); ! 610: } ! 611: } ! 612: ! 613: yearLength = tishri1After - tishri1; ! 614: day = inputDay - tishri1 - 29; ! 615: if (yearLength == 355 || yearLength == 385) { ! 616: /* Heshvan has 30 days */ ! 617: if (day <= 30) { ! 618: *pMonth = 2; ! 619: *pDay = day; ! 620: return; ! 621: } ! 622: day -= 30; ! 623: } else { ! 624: /* Heshvan has 29 days */ ! 625: if (day <= 29) { ! 626: *pMonth = 2; ! 627: *pDay = day; ! 628: return; ! 629: } ! 630: day -= 29; ! 631: } ! 632: ! 633: /* It has to be Kislev. */ ! 634: *pMonth = 3; ! 635: *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: { ! 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: if (year <= 0 || day <= 0 || day > 30) { ! 662: return (0); ! 663: } ! 664: switch (month) { ! 665: case 1: ! 666: case 2: ! 667: /* It is Tishri or Heshvan - don't need the year length. */ ! 668: FindStartOfYear(year, &metonicCycle, &metonicYear, ! 669: &moladDay, &moladHalakim, &tishri1); ! 670: if (month == 1) { ! 671: sdn = tishri1 + day - 1; ! 672: } else { ! 673: sdn = tishri1 + day + 29; ! 674: } ! 675: break; ! 676: ! 677: case 3: ! 678: /* It is Kislev - must find the year length. */ ! 679: ! 680: /* Find the start of the year. */ ! 681: FindStartOfYear(year, &metonicCycle, &metonicYear, ! 682: &moladDay, &moladHalakim, &tishri1); ! 683: ! 684: /* Find the end of the year. */ ! 685: moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; ! 686: moladDay += moladHalakim / HALAKIM_PER_DAY; ! 687: moladHalakim = moladHalakim % HALAKIM_PER_DAY; ! 688: tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); ! 689: ! 690: yearLength = tishri1After - tishri1; ! 691: ! 692: if (yearLength == 355 || yearLength == 385) { ! 693: sdn = tishri1 + day + 59; ! 694: } else { ! 695: sdn = tishri1 + day + 58; ! 696: } ! 697: 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: FindStartOfYear(year + 1, &metonicCycle, &metonicYear, ! 705: &moladDay, &moladHalakim, &tishri1After); ! 706: ! 707: if (monthsPerYear[(year - 1) % 19] == 12) { ! 708: lengthOfAdarIAndII = 29; ! 709: } else { ! 710: lengthOfAdarIAndII = 59; ! 711: } ! 712: ! 713: if (month == 4) { ! 714: sdn = tishri1After + day - lengthOfAdarIAndII - 237; ! 715: } else if (month == 5) { ! 716: sdn = tishri1After + day - lengthOfAdarIAndII - 208; ! 717: } else { ! 718: sdn = tishri1After + day - lengthOfAdarIAndII - 178; ! 719: } ! 720: break; ! 721: ! 722: default: ! 723: /* It is Adar II or later - don't need the year length. */ ! 724: FindStartOfYear(year + 1, &metonicCycle, &metonicYear, ! 725: &moladDay, &moladHalakim, &tishri1After); ! 726: ! 727: switch (month) { ! 728: case 7: ! 729: sdn = tishri1After + day - 207; ! 730: break; ! 731: case 8: ! 732: sdn = tishri1After + day - 178; ! 733: break; ! 734: case 9: ! 735: sdn = tishri1After + day - 148; ! 736: break; ! 737: case 10: ! 738: sdn = tishri1After + day - 119; ! 739: break; ! 740: case 11: ! 741: sdn = tishri1After + day - 89; ! 742: break; ! 743: case 12: ! 744: sdn = tishri1After + day - 60; ! 745: break; ! 746: case 13: ! 747: sdn = tishri1After + day - 30; ! 748: break; ! 749: default: ! 750: return (0); ! 751: } ! 752: } ! 753: 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: */