//Jewish calendar calculations from Judaism 101, http://www.jewfaq.org //Designed to illustrate the principles of calendar calculation // discussed at http://www.jewfaq.org/calendr2.htm function Molad() { //Create a user-defined object to store molad dates or // elapsed molad time. Object has the following properties: // P[arts], H[ours], D[ays], Y[ear], E[lapsed] and G[regorian Equivalent] this.P = 0; this.H = 0; this.D = 0; this.Y = 0; this.E = 0; this.G = ""; } //Step 1: Start with a Known Molad // Define the variable BaseMolad, which is // Molad Tishri in the Jewish year 5732 // used as a basis for other calculations BaseMolad = new Molad(); BaseMolad.D = 2; BaseMolad.H = 7; BaseMolad.P = 743; BaseMolad.Y = 5732; BaseMolad.G = new Date(1971, 8, 20); //Step 2: Determine the Number of Months to Tishri of Your Year // You will need to know if a year is a leap year to know how many months it has function IsLeapYear(HebYear) { switch(HebYear % 19) { // A cycle is 19 years case 0 : case 3 : case 6 : case 8 : // Years 3, 6, 8, 11, 14, 17 and 19 case 11 : case 14 : case 17 : // (that is, remainder 0) of a cycle return true; break; // are leap years default : // The rest are not return false; break; } } function MonthsBetween(StartYear, EndYear) { //StartYear is the Jewish year of your BaseMolad, ie, BaseMolad.Y //EndYear is the year you are calculating //This function does not accurately handle the possibility // that the year you are calculating is before the StartYear, // so you must either change the BaseMolad // or change the function to calculate dates before 1 Tishri 5732 Cycles = parseInt((EndYear-StartYear)/19); // Each complete cycle of 19 years MB = Cycles * 235; // has 235 months RemainingYear = StartYear + (19 * Cycles); //Remaining years must be calculated individually for (HebYear = RemainingYear; HebYear < EndYear; HebYear++) { if (IsLeapYear(HebYear)) { //if it is a leap year... MB = MB + 13; //... it has 13 months } else { //otherwise... MB = MB + 12 //... it has 12 months } } return MB; } //Step 3: Multiply the Number of Months by the Length of the Molad function ElapsedTime(Months) { //The elapsed time of one month is 29d 12h 793p Elapsed = new Molad(); Elapsed.P = (793 * Months); //multiply parts per month by number of months Elapsed.H = (12 * Months); //multiply hours per month by number of months Elapsed.D = (29 * Months); //multiply days per month by number of months Elapsed.H = Elapsed.H + parseInt(Elapsed.P / 1080); //rount parts into hours... Elapsed.P = Elapsed.P % 1080; //... and keep the remainder Elapsed.D = Elapsed.D + parseInt(Elapsed.H / 24); //round hours into days... Elapsed.H = Elapsed.H % 24; //... and keep the remainder return Elapsed; } //Step 4: Add the Result to the Starting Molad function AddToBase(BaseMolad, Elapsed) { //Elapsed is the molad calculated by the function above // which holds the amount of time elapsed between // the BaseMolad and the end date we are calculating Added = new Molad(); Added.P = Elapsed.P + BaseMolad.P; //add the elapsed parts to the starting parts Added.H = Elapsed.H + BaseMolad.H; //add the elapsed hours to the starting hours Added.D = Elapsed.D; //do not add starting days to the elapsed days yet Added.H = Added.H + parseInt(Added.P / 1080); //round parts into hours... Added.P = Added.P % 1080; //... and keep the remainder Added.D = Added.D + parseInt(Added.H / 24); //round hours into days... Added.H = Added.H % 24; //... and keep the remainder Added.E = Added.D; //elapsed days is the number of days before adding the starting days Added.D = Added.D + BaseMolad.D; //now we can add the starting days... Added.D = Added.D % 7; //...and keep the remainder after rounding out the weeks if (Added.D == 0) { Added.D = 7; } //If the remainder is 0, it's really 7, that is Saturday, Shabbat return Added; } //Dechiyah 1: Molad Zakein function Dechiyah1(Hour) { //where Hour is the hour from the calculated molad if (Hour >= 18) { //if the molad is after noon (18h)... Add = 1; //... add a day to get Rosh Hashanah } else { //otherwise... Add = 0; //...don't add a day } return Add; //this result will be added to the the .E of our calculated molad // for purposes of calculating the Gregorian date } //Dechiyah 2: Lo A"DU Rosh function Dechiyah2(Weekday) { //where Weekday is the day from the calculated molad // adjusted by rules of Molad Zakein if applicable switch (Weekday) { case 1 : //if Rosh Hashanah is on a Sunday... case 4 : //...or a Wednesday... case 6 : //...or a Friday... Add = 1; //...add a day break; default : //otherwise... Add = 0; //...don't add a day break; } return Add; } //Dechiyah 3: Gatarad function Dechiyah3(myMolad, HebYear) { Add = 0; //assume that no days will be added if (!IsLeapYear(HebYear)) { //if the current year is not a leap year... if (myMolad.D == 3) { //...and the Molad occurs on Tuesday... if (myMolad.H == 9 && myMolad.P >= 204) { //...and the Molad occurs in the 9th hour at or after 204 parts... Add = 2; //...then add 2 days -- one for Gatarad and one for Lo A"DU Rosh } if (myMolad.H > 9 && myMolad.H < 18) { //if it's a non-leap year and the Molad occurs on Tuesday after the 9th hour but before the 18th (when Molad Zakein takes over)... Add = 2; //...then add 2 days -- one for Gatarad and one for Lo A"DU Rosh } } } return Add; } //Dechiyah 4: Betutkafot function Dechiyah4(myMolad, HebYear) { Add = 0; //assume that no days will be added if (IsLeapYear(HebYear -1)) { //if the preceeding year was a leap year... if (myMolad.D == 2) { //...and the Molad occurs on Monday... if (myMolad.H == 15 && myMolad.P >= 589) { //...and the Molad occurs in the 15th hour at or after 589 parts... Add = 1; //...then add one day } if (myMolad.H > 15 && myMolad.H < 18) { //if it's the year after a leap year and the Molad occurs on Monday after the 15th hour but before the 18th (when Molad Zakein takes over)... Add = 1; //...then add one day } } } return Add; } function CalcRH(HebYear) { Months = MonthsBetween(BaseMolad.Y, HebYear); Elapsed = ElapsedTime(Months); myMolad = AddToBase(BaseMolad, Elapsed); Added = Dechiyah1(myMolad.H); Added = Added + Dechiyah2((myMolad.D + Added) % 7); Added = Added + Dechiyah3(myMolad, HebYear); Added = Added + Dechiyah4(myMolad, HebYear); return ConvertGreg(BaseMolad.G, myMolad.E + Added); } function CalcOther(HebMonth, HebDay, HebYear) { HebMonth = parseInt(HebMonth); HebDay = parseInt(HebDay); HebYear = parseInt(HebYear); switch (HebMonth) { case 7 : //Tishri Rosh = CalcRH(HebYear); return ConvertGreg(Rosh, HebDay - 1); break; case 8 : //Cheshvan Rosh = CalcRH(HebYear); return ConvertGreg(Rosh, 29 + HebDay); break; case 9 : //Kislev Rosh = CalcRH(HebYear); Offset = KislevOffset(HebYear); return ConvertGreg(Rosh, Offset + HebDay); break; case 10 : //Tevet Offset = -266; if (IsLeapYear(HebYear)) { Offset = Offset - 30; } Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 11 : //Shevat Offset = -237; if (IsLeapYear(HebYear)) { Offset = Offset - 30; } Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 12 : //Adar or Adar I Offset = -207; if (IsLeapYear(HebYear)) { Offset = Offset - 30; } Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 13 : //Adar II Offset = -207; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 1 : //Nissan Offset = -178; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 2 : //Iyar Offset = -148; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 3 : //Sivan Offset = -119; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 4 : //Tammuz Offset = -89; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 5 : //Av Offset = -60; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; case 6 : //Elul Offset = -30; Rosh = CalcRH(HebYear + 1); return ConvertGreg(Rosh, Offset + HebDay); break; } } function ConvertGreg(StartingGreg, Elapsed) { //adds a specific number of days to a Gregorian date //StartingGreg is the Gregorian date to start with // need to make sure it's a Date object //Elapsed is the number of days to add StartingGreg = new Date(StartingGreg); mn = StartingGreg.getMonth(); dy = StartingGreg.getDate(); yr = StartingGreg.getFullYear(); EndingGreg = new Date(yr, mn, dy + Elapsed); return formatDate(EndingGreg); } function KislevOffset(Year) { // returns the number of days from Rosh Hashanah to 1 Kislev // this varies because the length of Cheshvan (the preceding month) varies // you can't calculate backwards from the end of the year, because Kislev also varies OneDay = 1000*60*60*24 // milliseconds in a day, more or less RH1 = new Date(CalcRH(Year)); RH2 = new Date(CalcRH(Year + 1)); Elapsed = (RH2 - RH1) / OneDay; switch (Elapsed) { case 355: case 385: return 59; default: return 58; } } function formatDate(theDate) { // returns a secular date as text in m/d/yyyy format // getMonth() returns a month number 1 less than you would expect // getMonth() for a January date is 0! mn = theDate.getMonth() + 1; dy = theDate.getDate(); yr = theDate.getFullYear(); return mn + "/" + dy + "/" + yr; }