24

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));
    }
}
6
  • 1
    Although I occasionally program, I don't have complete competence of your .NET code. Regardless, I recommend that you look at Hebcal.com. Last I recall, I think they have alink to some code that determines how to calculate dates in the Hebrew calendar. In summary, there is no "general" rule for "add a year", since the rules for chaser and maleh are really based on Rosh Hashannah molad, leap year AND postponement rules. I recommend that you read up on these rules before you begin "quick coding".
    – DanF
    Commented Jun 6, 2014 at 16:36
  • @DanF: I've got working code for calculating a date in terms of converting between the Gregorian calendar and the Hebrew calendar, working out when leap years are, how long months are etc... but that's a different matter. If there isn't a generally-accepted answer for any given date, then I'll probably just use my proposal as a "generally sensible" one :)
    – Jon Skeet
    Commented Jun 6, 2014 at 16:39
  • Relevant: judaism.stackexchange.com/a/34768
    – msh210
    Commented Jun 9, 2014 at 21:11
  • See also: Ancient Hebrew Calendar(s) and Modern Translations of "Years"
    – Caleb
    Commented Jun 16, 2014 at 20:46
  • Related: judaism.stackexchange.com/q/49151
    – msh210
    Commented Dec 8, 2014 at 6:02

2 Answers 2

17

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.

6
  • 2
    Is the halacha the same for a shtar (e.g. a loan payable in exactly one year)? I think that would be the more relevant context in this case.
    – Yishai
    Commented Jun 6, 2014 at 19:44
  • @Yishai - interesting point. I will have to look into this, but my guess is that like nedarim, loans are dependent on idiomatic usage (lashon bnei adam) and since both 1 Kislev and 30 Chesvan or called Rosh Chodesh Kislev (see Magen Avraham, ibid), they are equivalent as stated in the answer.
    – Yoni
    Commented Jun 6, 2014 at 20:42
  • Thanks very much. I was hoping that it was sufficiently context-specific that the more consistent-with-Noda-Time rule would be good enough, but it sounds like the the "1st of the next month" rule is a more reasonable default. The implementation will be very simple - it's working out where to document it that's trickier ;)
    – Jon Skeet
    Commented Jun 7, 2014 at 7:39
  • @yoni, I looked it up, and you are correct, it is loshon bnei adam dependent. The 30th one year would be rosh chodesh the next.
    – Yishai
    Commented Jun 8, 2014 at 2:04
  • 1
    @JonSkeet worth noting as well that when a one year lapses when you start from Adar in under debate (surprise surprise) if the next year is leap. For periods of mourning calculations or commemoration ceremonies some would consider Adar I to be the year-after, some would only wait for Adar II. And there are more such examples, so I wouldn't try and expose all of them via the API...
    – synhershko
    Commented Jun 10, 2014 at 20:04
2

You are correct, for Adar I and Adar II the result of adding a year generally will be Adar II as the first Adar (Adar I) is the one that is the added month.

As for the extra day in a month, generally everything would be pushed a day forward. (30 Cheshvan == 1 Kislev).

(There are exceptions to this, but I think as a general rule - you cover most cases that your calendar would be utilized for. Maybe adding an overload to do a "dumb" calculation ala Microsoft's implentation would be beneficial.)

1
  • 2
    Hi HyShai! Welcome to Mi Yodeya, and thanks very much for posting this answer. Your post will be more valuable if you edit in sources for your assertions. I hope you'll look around the site and find other posts worth your time, perhaps including our 189 other calendar questions.
    – Isaac Moses
    Commented Jun 6, 2014 at 17:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .