The following comments indicate some potential problems linked to Hebrew-Gregorian date conversions. As with all date conversion functions, you are advised to check results against a reliable source and ensure they match the religious, traditional and cultural expectations of your target audience.
- The Hebrew calandar day does not start at midnight. It normally runs from dusk/sunset/6pm on one Gregorian Day to dusk/sunset/6pm on the next Gregorain day. (Exact timings can vary.)
- The Gregorian date returned by the main conversion usually relates to the Gregorian Date a few moments after the start of the new Hebrew day.
- The number of days in a Lunar year can vary between 354 and 385 days. (The Gregorian Calendar only varies between 365 and 366 days.)
- The first day of the Hebrew calendar (Rosh Hashanah) can fall anywhere in the Gregorian period of 5 September to 5 October
- Normally, a Gregorain year will have a single date matching a Hebrew festival.
- Occassionally, a single Gregorian Year will contain the same festival from 2 successive Hebrew years (when festival lands each side of 1 Jan). You can also get Gregorian years where a specified festival does not occur.
- The Hebrew calendar uses a "Leap Month" to remain "approximately" aligned with a solar year. The repeated month wil be Adar and can be renamed Adar1 and Adar2 to avoid confusion.
- The Adar "Leap Month" will only occur in Hebrew leap years. Normal years hace 12 months and leap years have 13 months.
- The Hebrew months of Ḥeshvan and Kislev can have either 29 or 30 days. (Similar to the Gregorian month of February having either 28 or 29 days)
- Converting dates within the original and repeated month of a leap year may require additional knowledge.(To decide if the date should relate to Adar-1 or Adar-2
- Geographic location, local time and cultural differences affect Calendrical Calculations. E.g. Some important Jeweish dates are celebrated 1 (Hebrew) day later in Jerusalem than in most of Europe
- Some festival dates are "normally" held on a specific Hebrew Month/Day but an adjustment (known as a "Postponement") is required under specific circumstances
- Some events only apply between approximately dawn and and approximately dusk. When converted to Gregorian time, dawn is after midnight, hence, the Gregorian event start date wil be one day later than the "after dusk" Gregoarian date associated with the matching Hebrew month/day
- Due to regional/relgious variations and other complexities, it may be prudent to cross reference any important event dates against an appropriate trusted source
Get Gregorian Date relating to a Hebrew Date
Public Shared Function Hebrew_To_Gregorian(yyyy_Heb As Integer, mm_Heb As Integer, dd_Heb As Integer) As Date
Dim date_Greg As Date
Try
Dim calendar_Heb As New Globalization.HebrewCalendar
Dim calendar_Greg As New Globalization.GregorianCalendar
Dim hebrewDate As Date = calendar_Heb.ToDateTime(yyyy_Heb, mm_Heb, dd_Heb, 12, 0, 0, 0, 0)
date_Greg = New Date(calendar_Greg.GetYear(hebrewDate), calendar_Greg.GetMonth(hebrewDate), calendar_Greg.GetDayOfMonth(hebrewDate), 12, 0, 0, 0)
Catch ex As Exception
date_Greg = New Date(1800, 1, 1, 0, 0, 0, 0, 0) ' invalid date, returning an obviously incorrect value
End Try
' Caution - Hebrew date start at dusk not midnight!
Return date_Greg '.AddDays(-1)'
End Function
Get Hebrew Date relating to a Gregorian Date
Public Shared Function Gregorian_To_Hebrew(date_Greg As Date) As HebrewDate
' Unlike Gregorian Month numbers, Hebrew month numbers are not constant.
' During a Leap Year, all month numbers after the leap Month (Adur2) will increase by 1
' To avoid month number confusion, the returned structure includes the month name as a string and enum
Dim ret As HebrewDate
Dim dat As New Date(date_Greg.Year, date_Greg.Month, date_Greg.Day, 12, 0, 0, 0, 0)
' starting from midday(Greg) to avoid clock-change issues etc.
Dim calendar_Heb As New Globalization.HebrewCalendar
ret.yyyy_Heb = calendar_Heb.GetYear(dat)
ret.mm_Heb = calendar_Heb.GetMonth(dat)
ret.dd_Heb = calendar_Heb.GetDayOfMonth(dat)
Dim hebrewDate As Date = calendar_Heb.ToDateTime(ret.yyyy_Heb, ret.mm_Heb, ret.dd_Heb, 12, 0, 0, 0)
'
Dim HebrewMonthsNormal As String() = {"", "Tishrei", "Cheshvan", "Kislev", "Tevet", "Shevat", "Adar", "Nissan", "Iyar", "Sivan", "Tamuz", "Av", "Elul"}
Dim HebrewMonthsLeap As String() = {"", "Tishrei", "Cheshvan", "Kislev", "Tevet", "Shevat", "Adar", "Adar2", "Nissan", "Iyar", "Sivan", "Tamuz", "Av", "Elul"}
If calendar_Heb.IsLeapYear(ret.yyyy_Heb) Then
ret.monthName_Eng = HebrewMonthsLeap(ret.mm_Heb)
Else
ret.monthName_Eng = HebrewMonthsNormal(ret.mm_Heb)
End If
ret.monthName_Heb = hebrewDate.ToString("MMMM", CultureInfo.CreateSpecificCulture("he-IL"))
Return ret
End Function
'
Public Structure HebrewDate
Dim yyyy_Heb As Integer
Dim mm_Heb As Integer
Dim dd_Heb As Integer
Dim monthName_Heb As String
Dim monthName_Eng As String
End Structure
Convert Hebrew Month name to VB.Net Hebrew Month Number
Some Hebrew years have 12 months, others have 13. In a Hebrew leap year, all months after Adur are numbererd 1 more than in a normal year. This function resolves name to dotnet month number.
Public Shared Function HebrewMonthName_To_Number(yyyy_Heb As Integer, MMM_Heb As String) As Integer
' Expects English version of the Hebrew month name e.g ADAR2. Will tolerate minor spelling variations
' Unlike Gregorian Month numbers, Hebrew month numbers are not constant.
' During a Leap Year, all month numbers after the leap Month (Adar2) will increase by 1
' This function coverts a month name into the month number for that name/year.
' Function returns 0 when month could not be found e.g. Adur2 in non leap year
Dim FirstMonths() As String = {"ZZ", "TI", "CH", "KI", "TE", "SH", "AD"}
Dim LastMonths() As String = {"NI", "IY", "SI", "TA", "AV", "EL"}
Dim monthNumber As Integer
If MMM_Heb.Length < 2 Then Return 0
MMM_Heb = MMM_Heb.ToUpper
If Mid(MMM_Heb, 1, 1) = "A" AndAlso MMM_Heb.Contains("2"c) Then MMM_Heb = "A2"
If Mid(MMM_Heb, 1, 1) = "A" AndAlso MMM_Heb.Contains("II") Then MMM_Heb = "A2"
If MMM_Heb.Contains("LEAP") Then MMM_Heb = "A2"
MMM_Heb = Mid(MMM_Heb, 1, 2).ToUpper
Dim calendar_Heb As New Globalization.HebrewCalendar
Dim ListHebrewMonths As List(Of String) = FirstMonths.ToList
If calendar_Heb.IsLeapYear(yyyy_Heb) Then ListHebrewMonths.Add("A2")
If calendar_Heb.IsLeapYear(yyyy_Heb) = False AndAlso MMM_Heb = "A2" Then MMM_Heb = "AD"
ListHebrewMonths.AddRange(LastMonths.ToList)
monthNumber = ListHebrewMonths.IndexOf(MMM_Heb)
If monthNumber < 1 Then monthNumber = 0
Return monthNumber
End Function
Calculating Specific Hebrew Event Dates
Important - Some dates wil vary slightly according to religions variations, starting after Gregorian-Midnight or regional issues (often 1 day late in Jerusalem etc.)
Private Shared Function AsaraBTevet(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tevet"), 10)
End Function
Private Shared Function Chanukah_Start(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew + 1, HebrewMonthName_To_Number(yyyy_Hebrew, "Kislev"), 25).AddDays(-1)
End Function
Private Shared Function LagBaOmer(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew + 1, HebrewMonthName_To_Number(yyyy_Hebrew + 1, "Iyyar"), 18)
End Function
Private Shared Function PesachStart(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Nisan"), 15)
' Some texts reference 14 Nisan (slaughtering of the lamb) but the feast is linked to 15 Nisan
End Function
Private Shared Function Purim(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Adar2"), 14).ToString("ddd dd MM yyyy")
' In Jerusalem etc., Purim could be on 15 Adar insteaed of European 14 Adar
' Adar2 references Adar in normal years and Adar2 in leap years
End Function
Private Shared Function RoshHasganah(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 1).ToString("ddd dd MM yyyy")
End Function
Private Shared Function SavuotStart(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Sivan"), 6).ToString("ddd dd MM yyyy")
End Function
Private Shared Function ShivahAsarBTammuz(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tammuz"), 17).ToString("ddd dd MM yyyy")
End Function
Private Shared Function ShmininAtzeret(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 22).ToString("ddd dd MM yyyy")
End Function
Private Shared Function SimchatTorah(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 23).ToString("ddd dd MM yyyy")
End Function
Private Shared Function SukkotStart(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 15).ToString("ddd dd MM yyyy")
End Function
Private Shared Function TaanitBechorot(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Nisan"), 14).ToString("ddd dd MM yyyy")
End Function
Private Shared Function TaanitEster(yyyy_Hebrew As Integer) As Date
Dim ret as Date = Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Adar2"), 13)
' Apply Postponement rule
If ret.DayOfWeek = DayOfWeek.Saturday Then ret = ret.AddDays(-2)
Return ret
End Function
Private Shared Function TishaBAv(yyyy_Hebrew As Integer) As Date
Dim ret as Date = Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Av"), 9)
' Apply Postponement rule
If ret.DayOfWeek = DayOfWeek.Saturday Then ret = ret.AddDays(1)
Return ret
End Function
Private Shared Function TuBAv(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Av"), 15)
End Function
Private Shared Function TuBishvat(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Shevat"), 15)
End Function
Private Shared Function TzomGedaliah(yyyy_Hebrew As Integer) As Date
Dim ret As Date = Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 3)
' Apply Postponement rule
If ret.DayOfWeek = DayOfWeek.Saturday Then ret = ret.AddDays(1)
Return ret
End Function
Private Shared Fucntion TzomTammuz(yyyy_Hebrew As Integer) As Date
Dim ret As Date = Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tammuz"), 17)
' Apply Postponement rule
If ret.DayOfWeek = DayOfWeek.Saturday Then ret = ret.AddDays(1)
Return ret
End Function
Private Shared Function YomKippur(yyyy_Hebrew As Integer) As Date
Return Hebrew_To_Gregorian(yyyy_Hebrew, HebrewMonthName_To_Number(yyyy_Hebrew, "Tishri"), 10).ToString("ddd dd MM yyyy")
End Function
DigitalDan.co.uk