Rosh Hashanah and Yom Kippur Holiday Dates Revisited

J

jnf40

Ron Rosenfeld,

I found the following code that works up until I enter the Gregorian year
2024 (fiscal year), molad 5784, then it shows Rosh Hashanah beginning sundown
of 9/16/2023 and ending 9/18/2023 with Yom Kippur on 9/25/2023. The calendar
at http://www.jewfaq.org/calendar.htm however shows Rosh Hashanah beginning
sundown of 9/15/2023 and ending 9/17/2023 with Yom Kippur on 9/25/2023. Also
read after code:

Option Explicit

Public MyDate As Date
Public FiscalYear As Integer
Public FirstSheet As String
Public myRHYK As Date
Public myRHYK1 As Long
Public LH As Boolean
Public SK As Boolean
Public ECD As Long
Public ECD1 As Long
Public LpYr As Boolean
Public LpYr1 As Boolean

Private Sub CommandButton1_Click()
Sheets("Sheet1").Select
FiscalYear = Excel.Range("a1")
myRHYK = HebrewDate(FiscalYear - 1, 1, 1)
Sheets("SHEET1").Unprotect
Excel.Sheets("Sheet1").Range("b2") = myRHYK
If myRHYK = Format(myRHYK, "m/d/yyyy") Then
myRHYK = Range("b1").Value
Range("C1") = Format(Range("b1"), "dddd")
Range("C2") = Format(Range("b2"), "dddd")
Range("C3") = Format(Range("b3"), "dddd")
Range("C5") = Format(Range("b5"), "dddd")
Range("d1").Value = "Rosh Hashanah" & Chr(10) & "Begins at Sundown"
& Chr(10) & "on " & Range("C1") 'Format(myrhyk - 1, "dddd")
Range("d5").Value = "Yom Kippur"
End If
Range("a1").Select
Sheets("SHEET1").Protect
End Sub
Sub jdn_civil(jdn As Long, _
ByRef iYear As Integer, _
ByRef iMonth As Integer, _
ByRef iDay As Integer)
Dim l As Long
Dim k As Long
Dim n As Long
Dim i As Long
Dim j As Long
If (jdn > 2299160) Then
l = jdn + 68569
n = ((4 * l) \ 146097)
l = l - ((146097 * n + 3) \ 4)
i = ((4000 * (l + 1)) \ 1461001)
l = l - ((1461 * i) \ 4) + 31
j = ((80 * l) \ 2447)
iDay = l - ((2447 * j) \ 80)
l = (j \ 11)
iMonth = j + 2 - 12 * l
iYear = 100 * (n - 49) + i + l
End If
End Sub

'
Function HebrewDate(civilYear As Integer, _
hebrewMonth As Integer, _
hebrewDay As Integer, _
Optional CalendarType As Integer = 1) As String
Dim jdnJanuary1 As Long
Dim jdnHoliday As Long
Dim hebrewYear As Integer
Dim dummy1 As Integer
Dim dummy2 As Integer
Dim iYear As Integer
Dim iMonth As Integer
Dim iDay As Integer
Dim lYear As Long


lYear = CLng(civilYear)

jdnJanuary1 = ((1461 * (lYear + 4800 + ((1 - 14) \ 12))) \ 4) _
+ ((367 * (1 - 2 - 12 * (((1 - 14) \ 12)))) \ 12) _
- ((3 * (((lYear + 4900 + ((1 - 14) \ 12)) \ 100))) \ 4) _
+ 1 - 32075

Call jdn_hebrew(jdnJanuary1, hebrewYear, dummy1, dummy2)
jdnHoliday = hebrew_jdn(hebrewYear + 1, hebrewMonth, hebrewDay)

Call jdn_civil(jdnHoliday, iYear, iMonth, iDay)
HebrewDate = iMonth & "/" & iDay & "/" & iYear

End Function
'
Sub jdn_hebrew(jdn As Long, _
ByRef iYear As Integer, _
ByRef iMonth As Integer, _
ByRef iDay As Integer, _
Optional monthcoding As Integer = 1)
Dim InputJDN As Long
Dim tishri1 As Long
Dim LeftOverDays As Long
If jdn <= 347997 Then
iYear = 0
iMonth = 0
iDay = 0
Else
InputJDN = jdn - 347997
iYear = (InputJDN \ 365) + 1
tishri1 = Hebrew_ElapsedCalendarDays(iYear)
While (tishri1 > InputJDN)
iYear = iYear - 1
tishri1 = Hebrew_ElapsedCalendarDays(iYear)
Wend
iMonth = 1
LeftOverDays = InputJDN - tishri1
ECD = Hebrew_ElapsedCalendarDays(iYear)
ECD1 = Hebrew_ElapsedCalendarDays(iYear + 1)
LH = (((ECD1 - ECD) Mod 10) = 5)
SK = (((ECD1 - ECD) Mod 10) = 3)

While (LeftOverDays >= Hebrew_LastDayOfMonth(iYear, iMonth))
LeftOverDays = LeftOverDays - Hebrew_LastDayOfMonth(iYear, iMonth)
iMonth = iMonth + 1
Wend
If Sgn(monthcoding) = -1 Then
If iMonth > 6 Then
If ((((7 * iYear) + 1) Mod 19) < 7) Then
iMonth = iMonth - 14
Else
iMonth = iMonth - 13
End If
End If
End If
iDay = LeftOverDays + 1
End If
End Sub
'
'
Function Hebrew_LastDayOfMonth(iYear, ByVal iMonth) As Integer
LpYr = ((((7 * iYear) + 1) Mod 19) < 7)
LpYr1 = ((((7 * (iYear - 1)) + 1) Mod 19) < 7)
If ((iMonth > 6) And (Not (LpYr))) Then
iMonth = iMonth + 1
End If
Select Case iMonth
Case 2
If LH Then
Hebrew_LastDayOfMonth = 30
Else
Hebrew_LastDayOfMonth = 29
End If
Case 3
If SK Then
Hebrew_LastDayOfMonth = 29
Else
Hebrew_LastDayOfMonth = 30
End If
Case 6
If LpYr Then
Hebrew_LastDayOfMonth = 30
Else
Hebrew_LastDayOfMonth = 29
End If
Case 4, 7, 9, 11, 13
Hebrew_LastDayOfMonth = 29
Case Else
Hebrew_LastDayOfMonth = 30
End Select
End Function
'
'
'
'
Function hebrew_jdn(iYear, ByVal iMonth, iDay) As Long
Dim jdn As Long
Dim counter As Integer
If iMonth < 0 Then
If LpYr Then
iMonth = 14 + iMonth
Else
iMonth = 13 + iMonth
End If
End If
jdn = Hebrew_ElapsedCalendarDays(iYear)
For counter = 1 To (iMonth - 1) Step 1
jdn = jdn + Hebrew_LastDayOfMonth(iYear, counter)
Next counter
hebrew_jdn = jdn + (iDay - 1 + 347997)
End Function
'
'
'
'
Function Hebrew_ElapsedCalendarDays(iYear) As Long
Dim MonthsElapsed As Long
Dim PartsElapsed As Long
Dim HoursElapsed As Long
Dim ConjunctionDay As Long
Dim ConjunctionParts As Long
Dim AlternativeDay As Long
LpYr = ((((7 * iYear) + 1) Mod 19) < 7)
LpYr1 = ((((7 * (iYear - 1)) + 1) Mod 19) < 7)
MonthsElapsed = (235 * (((iYear - 1) \ 19))) + _
(12 * ((iYear - 1) Mod 19)) + _
(7 * ((iYear - 1) Mod 19) + 1) \ 19
PartsElapsed = 204 + 793 * (MonthsElapsed Mod 1080)
HoursElapsed = 5 + 12 * MonthsElapsed + _
793 * ((MonthsElapsed \ 1080)) + _
PartsElapsed \ 1080
ConjunctionDay = 1 + 29 * MonthsElapsed + HoursElapsed \ 24
ConjunctionParts = (1080 * (HoursElapsed Mod 24)) + _
PartsElapsed Mod 1080
If ((ConjunctionParts >= 19440) Or _
(((ConjunctionDay Mod 7) = 2) And _
(ConjunctionParts >= 9924) And _
(Not (LpYr))) Or _
(((ConjunctionDay Mod 7) = 1) And _
(ConjunctionParts >= 16789) And _
(LpYr1))) _
Then
AlternativeDay = ConjunctionDay + 1
Else
AlternativeDay = ConjunctionDay
End If
If (((AlternativeDay Mod 7) = 0) Or _
((AlternativeDay Mod 7) = 3) Or _
((AlternativeDay Mod 7) = 5)) _
Then
AlternativeDay = AlternativeDay + 1
End If
Hebrew_ElapsedCalendarDays = AlternativeDay
End Function

On the web site you listed, http://www.jewfaq.org/calendar.htm, I found the
following code in JavaScript and the last bit of code is in VBScript:

JavaScript

//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 5759
// used as a basis for other calculations
BaseMolad = new Molad();
BaseMolad.D = 2;
BaseMolad.H = 12;
BaseMolad.P = 1005;
BaseMolad.Y = 5759;
BaseMolad.G = "9/21/1998";

//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 5759
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);
RHDate = ConvertGreg(BaseMolad.G, myMolad.E + Added);
return RHDate;
}

function CalcOther(HebMonth, HebDay, HebYear){
switch (HebMonth) {
case 7 : //Tishri
RH = CalcRH(HebYear);
return ConvertGreg(RH, HebDay - 1);
break;
case 8 : //Cheshvan
RH = CalcRH(HebYear);
return ConvertGreg(RH, 29 + HebDay);
break;
case 9 : //Kislev
thisRH = CalcRH(HebYear);
nextRH = CalcRH(HebYear + 1);
Offset = KislevOffset(thisRH, nextRH);
return ConvertGreg(thisRH, Offset + HebDay);
break;
case 10 : //Tevet
Offset = -266;
if (IsLeapYear(HebYear)) {
Offset = Offset - 30;
}
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 11 : //Shevat
Offset = -237;
if (IsLeapYear(HebYear)) {
Offset = Offset - 30;
}
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 12 : //Adar or Adar I
Offset = -207;
if (IsLeapYear(HebYear)) {
Offset = Offset - 30;
}
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 13 : //Adar II
Offset = -207;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 1 : //Nissan
Offset = -178;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 2 : //Iyar
Offset = -148;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 3 : //Sivan
Offset = -119;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 4 : //Tammuz
Offset = -89;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 5 : //Av
Offset = -60;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
case 6 : //Elul
Offset = -30;
RH = CalcRH(HebYear + 1);
return ConvertGreg(RH, Offset + HebDay);
break;
}
}

VBScript

Function ConvertGreg(StartingGreg, Elapsed)
'adds a specific number of days to a Gregorian date
'StartingGreg is the Gregorian date to start with
'Elapsed is the number of days to add

ConvertGreg = DateAdd("d", Elapsed, StartingGreg)
ConvertGreg = FormatDateTime(ConvertGreg, vbShortDate)
End Function

Function KislevOffset(StartRH, EndRH)
Select Case DateDiff("d", StartRH, EndRH)
Case 353, 383, 354, 384
KislevOffset = 58
Case 355, 385
KislevOffset = 59
End Select
End Function


I know nothing about how to even begin to change the JavaScript to VBScript.
 
R

Ron Rosenfeld

Ron Rosenfeld,

I found the following code that works up until I enter the Gregorian year
2024 (fiscal year), molad 5784, then it shows Rosh Hashanah beginning sundown
of 9/16/2023 and ending 9/18/2023 with Yom Kippur on 9/25/2023. The calendar
at http://www.jewfaq.org/calendar.htm however shows Rosh Hashanah beginning
sundown of 9/15/2023 and ending 9/17/2023 with Yom Kippur on 9/25/2023. Also
read after code:

jnf40,

Personally, I use Calendar Creator to obtain the dates of Jewish Holidays. Its
built-in algorithm seems to work.

It, too, shows Rosh Hashanna beginning on the evening of 15 Sep 2023 and Yom
Kippur starting on the evening of 24 Sep 2023. So I would say the web site and
Calendar Creator are correct.

There is also an interactive calendar at http://www.hebcal.com/ with the
capability of downloading the results into various formats, including CSV file
(designed for Outlook but opens fine in Excel).
--ron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top