Annotation of embedaddon/php/ext/calendar/jewish.c, revision 1.1
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: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>