Wednesday, 25 March 2015

How does one "add a year" in the Hebrew calendar?


I'm trying to support the Hebrew calendar in my Noda Time project, and need to support an operation of "add a year" - or more generally, answer the question of "Given an original date and a target year number, what's the resulting date?"



Firstly, I'd like to check that I'm correct in saying that Microsoft gets the answer wrong in .NET. For example, consider the date of this post: 8th of Sivan, 5774. Sivan is month 10 in the civil month numbering system in a leap year, and 5774 is a leap year. If we add one year to today's date, .NET keeps the month number (10) leaving us with 8th of Tamuz, 5775 - because 5775 is not a leap year. (Supporting code is at the bottom of this question1.) To me, this feels incorrect - it's the month itself that should be preserved, not the month number.


Assuming that my approach is correct (and that we should more reasonably end up with a month number of 9, which is Sivan in a non-leap year), that still leaves some edge cases:



  • What should we do if we add a year to the 30th of Heshvan, and Heshvan only has 29 days in the resulting year?

  • Similarly, what should we do if we add a year to the 30th of Kislev, and Kislev only has 29 days in the resulting year?

  • What should we do if we add a year to a date in Adar I, resulting in a non-leap year?

    • Special case: what should we do if we add a year to the 30th of Adar I?




  • What should we do if we add a year to a date in Adar II, resulting in a non-leap year?

  • What should we do if we add a year to a date in Adar, resulting in a leap year?


I have a proposal:



  • If you start with a date in Adar I or Adar II and the target year is not a leap year, the result should be in Adar

  • If you start with a date in Adar and the target year is a leap year, the result should be in Adar II

  • If the result would be longer than the month length in the target yet, truncate to the last day of the month (so 30th of Adar I would map to 29th of Adar, and the Heshvan/Kislev examples would both truncate to the 29th of the same month)


I believe this is close to but not quite the same as the birthday rule specified in Calendrical Calculations (documented for Hebcal), where 30th of (Adar I/Kislev/Heshvan) would be mapped to 1st of the next month... but so long as the above proposal is reasonable under Jewish tradition, it would be more consistent with other aspects of my code. (I'm happy to throw consistency out of the window if there's good cause, but I'd prefer to keep it otherwise.)



One problematic aspect of all of this is that it has to be context-free. I'm aware that there may very well be different rules for different contexts, but I need to have a "general purpose" rule, unfortunately.


So, is this a reasonable proposal, or do I still have a lot to learn about how to answer even simple questions about the Hebrew calendar?




1 Reference .NET code:


using System;
using System.Globalization;

class Test
{
static void Main()

{
var calendar = new HebrewCalendar();
DateTime start = new DateTime(5774, 10, 8, calendar);
// Prints 5774-10-08
Console.WriteLine(FormatYearMonthDay(start, calendar));
DateTime end = calendar.AddYears(start, 1);
// Prints 5775-10-08
Console.WriteLine(FormatYearMonthDay(end, calendar));
}


static string FormatYearMonthDay(DateTime date, Calendar calendar)
{
return string.Format("{0}-{1}-{2}",
calendar.GetYear(date),
calendar.GetMonth(date),
calendar.GetDayOfMonth(date));
}
}

Answer



You are correct that the .NET implementation is apparently not consistent with Halacha (i.e. Jewish law) (Orach Chaim 55:10 and Mishne Berurah ibid) and your first 2 rules are correct and consistent with Halacha.



Jewish law (ibid, MB 45) calculations are correctly implemented in HebCal contrary to your third rule. Specifically, if a boy is born on 30 Cheshvan, 5700, his Bar Mitzvah, celebrated 13 years hence, will fall on 1 Kislev, 5713.


Interestingly, if a boy is born on 1 Kislev, 5700 when Cheshvan had only 29 days, he will celebrate his Bar Mitzvah on 30 Cheshvan, 5713. Speculatively, perhaps HebCal omits this rule since it may be context-dependent on Bar Mitzvah, is a subject of debate (see Shaarei Teshuva, ibid), and also seems anomalous. See here for the rationale of this ruling (page 11, top) .


My guess is that users of Hebrew calendar calculations (like me !) will expect consistency with Jewish law because that is likely why they are using the calendar in the first place. Any other implementation will be confusing - despite the algorithmic elegance or consistency with existing code.


If I were to implement this feature I would likely follow the HebCal rules and possibly overload the addYears method to take a boolean isBarMitzva parameter that will be consistent with the Bar Mitzva rules. This way users will understand that the calendrical calculations may follow different rules and won't get unexpected results.




P.S. I'm a big fan of your "C# in Depth" and recommend that all my students get it.


No comments:

Post a Comment

readings - Appending 内 to a company name is read ない or うち?

For example, if I say マイクロソフト内のパートナーシップは強いです, is the 内 here read as うち or ない? Answer 「内」 in the form: 「Proper Noun + 内」 is always read 「ない...