📄 jewish.c
字号:
static void MoladOfMetonicCycle( int metonicCycle, long int *pMoladDay, long int *pMoladHalakim){ register unsigned long int r1, r2, d1, d2; /* Start with the time of the first molad after creation. */ r1 = NEW_MOON_OF_CREATION; /* Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE. The upper 32 * bits of the result will be in r2 and the lower 16 bits will be * in r1. */ r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF); r2 = r1 >> 16; r2 += metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF); /* Calculate r2r1 / HALAKIM_PER_DAY. The remainder will be in r1, the * upper 16 bits of the quotient will be in d2 and the lower 16 bits * will be in d1. */ d2 = r2 / HALAKIM_PER_DAY; r2 -= d2 * HALAKIM_PER_DAY; r1 = (r2 << 16) | (r1 & 0xFFFF); d1 = r1 / HALAKIM_PER_DAY; r1 -= d1 * HALAKIM_PER_DAY; *pMoladDay = (d2 << 16) | d1; *pMoladHalakim = r1;}/************************************************************************ * Given a day number, find the molad of Tishri (the new moon at the start * of a year) which is closest to that day number. It's not really the * *closest* molad that we want here. If the input day is in the first two * months, we want the molad at the start of the year. If the input day is * in the fourth to last months, we want the molad at the end of the year. * If the input day is in the third month, it doesn't matter which molad is * returned, because both will be required. This type of "rounding" allows * us to avoid calculating the length of the year in most cases. */static void FindTishriMolad( long int inputDay, int *pMetonicCycle, int *pMetonicYear, long int *pMoladDay, long int *pMoladHalakim){ long int moladDay; long int moladHalakim; int metonicCycle; int metonicYear; /* Estimate the metonic cycle number. Note that this may be an under * estimate because there are 6939.6896 days in a metonic cycle not * 6940, but it will never be an over estimate. The loop below will * correct for any error in this estimate. */ metonicCycle = (inputDay + 310) / 6940; /* Calculate the time of the starting molad for this metonic cycle. */ MoladOfMetonicCycle(metonicCycle, &moladDay, &moladHalakim); /* If the above was an under estimate, increment the cycle number until * the correct one is found. For modern dates this loop is about 98.6% * likely to not execute, even once, because the above estimate is * really quite close. */ while (moladDay < inputDay - 6940 + 310) { metonicCycle++; moladHalakim += HALAKIM_PER_METONIC_CYCLE; moladDay += moladHalakim / HALAKIM_PER_DAY; moladHalakim = moladHalakim % HALAKIM_PER_DAY; } /* Find the molad of Tishri closest to this date. */ for (metonicYear = 0; metonicYear < 18; metonicYear++) { if (moladDay > inputDay - 74) { break; } moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; moladDay += moladHalakim / HALAKIM_PER_DAY; moladHalakim = moladHalakim % HALAKIM_PER_DAY; } *pMetonicCycle = metonicCycle; *pMetonicYear = metonicYear; *pMoladDay = moladDay; *pMoladHalakim = moladHalakim;}/************************************************************************ * Given a year, find the number of the first day of that year and the date * and time of the starting molad. */static void FindStartOfYear( int year, int *pMetonicCycle, int *pMetonicYear, long int *pMoladDay, long int *pMoladHalakim, int *pTishri1){ *pMetonicCycle = (year - 1) / 19; *pMetonicYear = (year - 1) % 19; MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim); *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear]; *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY; *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY; *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim);}/************************************************************************ * Given a serial day number (SDN), find the corresponding year, month and * day in the Jewish calendar. The three output values will always be * modified. If the input SDN is before the first day of year 1, they will * all be set to zero, otherwise *pYear will be > 0; *pMonth will be in the * range 1 to 13 inclusive; *pDay will be in the range 1 to 30 inclusive. */void SdnToJewish( long int sdn, int *pYear, int *pMonth, int *pDay){ long int inputDay; long int day; long int halakim; int metonicCycle; int metonicYear; int tishri1; int tishri1After; int yearLength; if (sdn <= SDN_OFFSET) { *pYear = 0; *pMonth = 0; *pDay = 0; return; } inputDay = sdn - SDN_OFFSET; FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim); tishri1 = Tishri1(metonicYear, day, halakim); if (inputDay >= tishri1) { /* It found Tishri 1 at the start of the year. */ *pYear = metonicCycle * 19 + metonicYear + 1; if (inputDay < tishri1 + 59) { if (inputDay < tishri1 + 30) { *pMonth = 1; *pDay = inputDay - tishri1 + 1; } else { *pMonth = 2; *pDay = inputDay - tishri1 - 29; } return; } /* We need the length of the year to figure this out, so find * Tishri 1 of the next year. */ halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; day += halakim / HALAKIM_PER_DAY; halakim = halakim % HALAKIM_PER_DAY; tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim); } else { /* It found Tishri 1 at the end of the year. */ *pYear = metonicCycle * 19 + metonicYear; if (inputDay >= tishri1 - 177) { /* It is one of the last 6 months of the year. */ if (inputDay > tishri1 - 30) { *pMonth = 13; *pDay = inputDay - tishri1 + 30; } else if (inputDay > tishri1 - 60) { *pMonth = 12; *pDay = inputDay - tishri1 + 60; } else if (inputDay > tishri1 - 89) { *pMonth = 11; *pDay = inputDay - tishri1 + 89; } else if (inputDay > tishri1 - 119) { *pMonth = 10; *pDay = inputDay - tishri1 + 119; } else if (inputDay > tishri1 - 148) { *pMonth = 9; *pDay = inputDay - tishri1 + 148; } else { *pMonth = 8; *pDay = inputDay - tishri1 + 178; } return; } else { if (monthsPerYear[(*pYear - 1) % 19] == 13) { *pMonth = 7; *pDay = inputDay - tishri1 + 207; if (*pDay > 0) return; (*pMonth)--; (*pDay) += 30; if (*pDay > 0) return; (*pMonth)--; (*pDay) += 30; } else { *pMonth = 6; *pDay = inputDay - tishri1 + 207; if (*pDay > 0) return; (*pMonth)--; (*pDay) += 30; } if (*pDay > 0) return; (*pMonth)--; (*pDay) += 29; if (*pDay > 0) return; /* We need the length of the year to figure this out, so find * Tishri 1 of this year. */ tishri1After = tishri1; FindTishriMolad(day - 365, &metonicCycle, &metonicYear, &day, &halakim); tishri1 = Tishri1(metonicYear, day, halakim); } } yearLength = tishri1After - tishri1; day = inputDay - tishri1 - 29; if (yearLength == 355 || yearLength == 385) { /* Heshvan has 30 days */ if (day <= 30) { *pMonth = 2; *pDay = day; return; } day -= 30; } else { /* Heshvan has 29 days */ if (day <= 29) { *pMonth = 2; *pDay = day; return; } day -= 29; } /* It has to be Kislev. */ *pMonth = 3; *pDay = day;}/************************************************************************ * Given a year, month and day in the Jewish calendar, find the * corresponding serial day number (SDN). Zero is returned when the input * date is detected as invalid. The return value will be > 0 for all valid * dates, but there are some invalid dates that will return a positive * value. To verify that a date is valid, convert it to SDN and then back * and compare with the original. */long int JewishToSdn( int year, int month, int day){ long int sdn; int metonicCycle; int metonicYear; int tishri1; int tishri1After; long int moladDay; long int moladHalakim; int yearLength; int lengthOfAdarIAndII; if (year <= 0 || day <= 0 || day > 30) { return (0); } switch (month) { case 1: case 2: /* It is Tishri or Heshvan - don't need the year length. */ FindStartOfYear(year, &metonicCycle, &metonicYear, &moladDay, &moladHalakim, &tishri1); if (month == 1) { sdn = tishri1 + day - 1; } else { sdn = tishri1 + day + 29; } break; case 3: /* It is Kislev - must find the year length. */ /* Find the start of the year. */ FindStartOfYear(year, &metonicCycle, &metonicYear, &moladDay, &moladHalakim, &tishri1); /* Find the end of the year. */ moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear]; moladDay += moladHalakim / HALAKIM_PER_DAY; moladHalakim = moladHalakim % HALAKIM_PER_DAY; tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim); yearLength = tishri1After - tishri1; if (yearLength == 355 || yearLength == 385) { sdn = tishri1 + day + 59; } else { sdn = tishri1 + day + 58; } break; case 4: case 5: case 6: /* It is Tevet, Shevat or Adar I - don't need the year length. */ FindStartOfYear(year + 1, &metonicCycle, &metonicYear, &moladDay, &moladHalakim, &tishri1After); if (monthsPerYear[(year - 1) % 19] == 12) { lengthOfAdarIAndII = 29; } else { lengthOfAdarIAndII = 59; } if (month == 4) { sdn = tishri1After + day - lengthOfAdarIAndII - 237; } else if (month == 5) { sdn = tishri1After + day - lengthOfAdarIAndII - 208; } else { sdn = tishri1After + day - lengthOfAdarIAndII - 178; } break; default: /* It is Adar II or later - don't need the year length. */ FindStartOfYear(year + 1, &metonicCycle, &metonicYear, &moladDay, &moladHalakim, &tishri1After); switch (month) { case 7: sdn = tishri1After + day - 207; break; case 8: sdn = tishri1After + day - 178; break; case 9: sdn = tishri1After + day - 148; break; case 10: sdn = tishri1After + day - 119; break; case 11: sdn = tishri1After + day - 89; break; case 12: sdn = tishri1After + day - 60; break; case 13: sdn = tishri1After + day - 30; break; default: return (0); } } return (sdn + SDN_OFFSET);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -