Reputation: 113
I have the following code, a simple example on which I want to expand to compute the Yartzeit dates (death anniversaries). The code adds 1 month to the Jewish date 5771/1/1. It gives me an exception and I can't figure out why (I have very little knowledge of Jewish dates):
Imports System
Imports System.Globalization
Imports System.Threading
Public Module Module1
Public Sub Main()
Dim hc As New HebrewCalendar()
Dim jewishCulture As CultureInfo = CultureInfo.CreateSpecificCulture("he-IL")
jewishCulture.DateTimeFormat.Calendar = hc
Thread.CurrentThread.CurrentUICulture = jewishCulture
Dim startDate = new DateTime(5771,1,1)
Console.WriteLine(startDate.ToString())
startDate = hc.AddMonths(startDate, 1)
Console.WriteLine(startDate.ToString())
End Sub
End Module
Here is the result (from .NET Fiddle, I have the same result locally):
1/1/5771 12:00:00 AM
Run-time exception (line -1): Value to add was out of range.
Parameter name: months
Stack Trace:
[System.ArgumentOutOfRangeException: Value to add was out of range.
Parameter name: months]
According to the documentation on the HebrewCalendar.AddMonths Method (http://msdn.microsoft.com/en-us/library/system.globalization.hebrewcalendar.addmonths(v=vs.110).aspx), the ArgumentOutOfRangeException should be thrown if "months is less than -120,000 or greater than 120,000.". This is obviously not the case here, I add 1 month to month #1. Are there known issues with the .NET HebrewCalendar class ? Or something else I am missing?
Thank you,
PS: I'm using the HebrewCalendar.AddMonths rather than the DateTime.AddMonths method because of the following remark on HebrewCalendar.AddMonths: "The day part of the resulting DateTime is affected if the resulting day is not a valid day in the resulting month of the resulting year. It is changed to the last valid day in the resulting month of the resulting year.".
Upvotes: 1
Views: 144
Reputation: 241450
There are two issues here:
You are assigning the culture to the CurrentUICulture
. That will have no effect on DateTime
. The UI culture determines which localization resource file to use if you have localized resx files. You should set the CurrentCulture
instead, which is used in number and date formatting.
Thread.CurrentThread.CurrentCulture = jewishCulture
If you're not using the Gregorian calendar when you construct a DateTime
from individual year, month, day parts, you must pass the calendar as a parameter. See the remarks in the MSDN docs.
Dim startDate = new DateTime(5771,1,1, hc)
Keep in mind that the DateTime
object itself is just a wrapper around the number of ticks passed since 0001/01/01 in the Gregorian calendar. It always uses the Gregorian calendar in its properties and methods. (If you look at startDate.Year
, it will be 2010, not 5771.)
To add "1 Hebrew month" - you must call HebrewCalendar.AddMonths
rather than DateTime.AddMonths
. You have this right, but it's not just for the reason you described.
Also, you may be interested in Jon Skeet's latest work in Noda Time 1.3 which adds experimental support for the Hebrew calendar. Please read under "Hebrew" in the user guide, and read the comments in the 1.3 release notes. In general, I trust Jon's interpretation of the Hebrew calendar better than I trust the .Net Framework's HebrewCalendar
class. (See this discussion.)
Upvotes: 1