בס"ד
by Dr. Irv Bromberg, University of Toronto, Canada
[Click here to go back to the Hebrew Calendar Studies home page]
This page discusses advanced aspects of the Rectified Hebrew Calendar, including arithmetic that is not essential for the calendar itself, as well as noteworthy variants of the calendar.
Characterof the Hebrew Year
The Delta
value (Δ), employed in the ElapsedMonths and isHebrewLeapYear functions (when Mode = Rectify is true), determines the calendar’s long-term alignment relative to the northward equinox. The optimal value to select depends on what is considered to be the desired equinox alignment. The following table compares the recommended value (Δ=138 and progressive molad) with a few alternatives. For each category of long-term alignment, two possible Δ values are quoted, depending on whether the calendar is to be used with the traditional or progressive molad:
Long-Term Equinox Alignment | Δ for Traditional Molad | Δ for Progressive Molad |
Reset average equinox to the start of Nisan, latest equinoxes on the first day of Passover | 133 | 138 |
Latest equinox at the Korban Pesach moment (14 Nisan, 1/2 hour after noon) | 146 | 150 |
Stop drift without equinox reset, leaving average equinox 5 days before start of Nisan | 195 | 199 |
The tabulated Δ values are optimal for the standard molad zakein rule applied to Rosh HaShanah, which requires postponement to the next allowable weekday if the molad of Tishrei lands on or after noon.
For any Δ value, the maintenance of the long-term equinox alignment will continue for about 3 millennia longer with the progressively shorter interval of the progressive molad than it will with the fixed progressively slightly too long interval of the traditional molad.
The following is an alternate version of the HebrewNewYear function, which uses a single modulus expression instead of the multi-part IF statement when checking for disallowed weekdays, and for the Tuesday and Monday rules instead of the calculating the length of the year it checks the weekday of the future or past MoladDay.
To work most efficiently, this version numbers the Hebrew weekdays from 0=Sunday through 6=Saturday. This alternate version generates Rosh HaShanah dates that are identical to the main version, for the Traditional or Rectified Hebrew calendars, and for the traditional or progressive molad.
The calling syntax for the HebrewNewYear function is:
RoshHaShanah = HebrewNewYear( Mode, hYear )
The HebrewNewYear function starts by using the ElapsedMonths function to find the Lunation number for Tishrei of the given year, depending on the specified Hebrew Calendar Mode:
Lunation = ElapsedMonths( Mode, hYear, Tishrei )
where Tishrei = 7, as it is the 7th month of the Hebrew Calendar.
Store the Lunation number in a local variable, because it will be needed again when processing the Tuesday or Monday Rosh HaShanah postponement rules.
Next use the MoladDay function to get the provisional fixed date of either the traditional or progressive molad, depending on the Hebrew Calendar Mode, with the molad zakein postponement rule already handled:
For checking the rest of the Rosh HaShanah postponement rules we need the Hebrew weekday of the molad, determined as an integer from 0=Sunday to 6=Saturday by keeping the remainder after dividing the provisional Rosh HaShanah fixed date by 7:
MoladWeekday = modulus( ThisHebrewNewYear, 7 )
If the provisional Rosh HaShanah date is on any of the disallowed weekdays (Sunday, Wednesday, Friday), even if it got there because of the Gauss (Gauß) +1/4 day shortcut, then we postpone Rosh HaShanah by one day. This is the most common reason for Rosh HaShanah postponement:
IF modulus( MoladWeekday × 3, 7 ) < 3 THEN ' check for disallowed Rosh HaShanah weekday
ThisHebrewNewYear = ThisHebrewNewYear + 1 ' postpone from disallowed to allowed weekday
For a slight gain in efficiency, because MoladWeekday is guaranteed to be a small non-negative integer, one could substitute the programming language’s built-in MOD operator by checking for (MoladWeekday × 3) MOD 7 < 3. However for other situations, including elsewhere within this alternate HebrewNewYear function, the modulus function is used instead of MOD, because in many programming environments the MOD operator doesn’t work properly with negative or real numbers.
For the Tuesday and Monday postponement rules that follow, I will omit the full discussion that is in the main HebrewNewYear function description, and will just show the alternate program code, which avoids calculating the length of the year:
ELSE IF MoladWeekday = 2 THEN ' Yom Shlishi (Tuesday), recall that weekdays in this variant 0=Sunday ... 2=Tuesday
IF NOT isHebrewLeapYear( Mode, hYear ) THEN ' this rule applies only if this is a non-leap year (12 months)
' recall that 0=Sunday in this variant, so we will check for zero
' and if zero then we postpone this year from Tuesday to Thursday
IF modulus( MoladDay( Mode, Lunation + 12 ), 7 ) = 0 THEN ThisHebrewNewYear = ThisHebrewNewYear +2END IF
ELSE IF MoladWeekday = 1 THEN ' Yom Sheini (Monday), recall that weekdays in this variant 0=Sunday, 1=Monday
IF isHebrewLeapYear( Mode, hYear – 1 ) THEN ' this rule applies only if previous year was leap (13 months)
' recall that 0=Sunday ... 3=Wednesday, so we will check for 3
' and if 3 then we postpone this year from Monday to Tuesday
IF modulus( MoladDay( Mode, Lunation – 13), 7 ) = 3 THEN ThisHebrewNewYear = ThisHebrewNewYear + 1END IF
END IF
The HebrewNewYear function finishes by simply returning the finalized Rosh HaShanah fixed date, which includes any postponements that were applied:
RETURN ThisHebrewNewYear
Characterof the Hebrew Year
The complete specification of any given Hebrew year, on either the Traditional or Rectified Hebrew Calendar, is given by the starting weekday numbers of Passover and Rosh HaShanah, a descriptor for the length of the year, and its leap status. Strictly speaking, the weekday of Passover is redundant, because the rest of the information suffices to fully characterize the year.
The character of the Hebrew year is of ritual significance because it determines the pattern of weekly portions of the Torah reading cycle. In addition, the starting weekday of Rosh HaShanah fixes the weekday pattern for all of the High Holy Days in Tishrei, and the starting weekday of Passover fixes the weekday pattern for all of the High Holy Days in Nisan and for Shavuot.
In the absence of Rosh HaShanah postponements there would be 4 possible year lengths that could start on any of 7 possible weekdays, which could combine to 28 possible year types. However, Rosh HaShanah can’t start on Sunday, Wednesday, or Friday. When Rosh HaShanah starts on Monday, Thursday, or Saturday there are only 4 possible year lengths, and when it starts on Tuesday there are only 2 possible year lengths. Thus the total number of possible year types is only 14.
Passover always starts on the same weekday as the month of Nisan. Use the NisanFirstDay function to return the fixed date of the start of Nisan, divide that by 7 and increment the remainder to yield its Hebrew weekday number (1=Sunday ... 7=Saturday):
PassoverWeekday = modulus( NisanFirstDay( Mode, hYear ) , 7 ) + 1
Passover is always 163 days before the next year’s Rosh HaShanah. In other words it is on the day that is 163 days before the date that is obtained by adding the length of the current year to the date of Rosh HaShanah of the current year. Recall that the NisanFirstDay function simply returns the date that is 177 days before the next year’s Rosh HaShanah date.
To calculate the starting weekday number for Rosh HaShanah, use the HebrewNewYear function to return the fixed date of Rosh HaShanah, divide that by 7 and increment the remainder to yield its Hebrew weekday number (1=Sunday ... 7=Saturday):
RoshHaShanahWeekday = modulus( HebrewNewYear( Mode, hYear ) , 7 ) + 1
The year length descriptors are:
English | Hebrew | Non-Leap Length | Leap Length | Days in Cheshvan | Days in Kislev |
---|---|---|---|---|---|
Deficient or Short | Chaser = חָסֵר | 353 | 383 | 29 | 29 |
Normal or Regular | K’sidrah = קסידרה | 354 | 384 | 30 | 29 |
Perfect or Full | Shalem = שלם | 355 | 385 | 30 | 30 |
The following function returns D
, N
or P
to indicate the Deficient
, Normal
or Perfect
length of the specified Hebrew year, respectively, appended with an asterisk if the specified year has 13 months:
YearLengthType( Mode, hYear ) =
YearLength = DaysInHebrewYear( Mode, hYear )
' indirectly determine leap status
IF YearLength > 355 THEN LeapFlag = "*" ELSE LeapFlag = ""CASE SELECT YearLength
CASE 353, 383 ' Deficient
RETURN "D" & LeapFlag
CASE 354, 384 ' Normal
RETURN "N" & LeapFlag
CASE 355, 385 ' Perfect
RETURN "P" & LeapFlag
END SELECT
Obviously, it would be easy to replace the above verbose but self-evident implementation with a single compact but more obscure expression. In some applications it might be advantageous to return the year length type numerically, for example −1=Deficient, 0=Normal, +1=Perfect, which are easily calculated by subtracting the normal length of a year (354 or 384, depending on leap status) from the actual length of the specified year.
Typically the year character information would be combined together, for example the character of the Traditional Hebrew Calendar year 5765 could be specified as 15D*
, meaning that Passover started on Sunday, Rosh HaShanah started on Thursday, it was a Deficient year, and the *
flags it as having been a leap year. The methods for combining and returning this information from a computer function depends on the programming environment and its intended use in the application environment, and therefore is not detailed here.
Over the long term, the frequency of occurrence of each of the Hebrew year types on the Rectified Hebrew Calendar is essentially the same as the Traditional Hebrew Calendar, but they sometimes differ regarding the type of individual years.
Optionally, one could implement the following inverse function for MoladMoment in Traditional mode, determining the Lunation number from a traditional Talmudic Temporal Time moment (or from a rata die moment by first adding 1/4 day to the moment). Once the Lunation number is known, one can find any prior or subsequent traditional molad simply by decrementing or incrementing the Lunation number as desired and then passing it back to the MoladMoment function in Traditional mode, or more directly by adding or subtracting multiples of the traditional molad interval.
TraditionalMomentToLunation( TTTmoment ) = ( TTTmoment – TraditionalMoladEpoch ) / MoladInterval
Using as an example 5.3 days after molad moment above:
( 732228.000462963 – TraditionalMoladEpoch ) / MoladInterval = 71304.1794748855
The returned Lunation number has a fractional part representing the elapsed portion of that molad interval up to the given moment. If desired, one can floor it to obtain the integer Lunation number that started that molad cycle, or round it to obtain the closest integer Lunation number.
At the time of writing, I can’t offer a good method for inverting the MoladMoment in Rectify mode, but there is really no need, because the inverse methods for the calculus based functions, discussed next, are entirely satisfactory.
Instead of an empirically based progressive molad function, one could use calculus to integrate the number of days from the progressive molad epoch to the desired progressive molad moment. For the number of elapsed lunar months, the integration calculates the area under the sloped line that defines the changing length of the Mean Synodic Month, by using a factored quadratic expression in terms of Lunation:
Lunation = ElapsedMonths( Rectify, hYear, hMonth )
AltProgressiveMolad( Lunation ) = Lunation × (MSMatEpoch + MSMslope × Lunation / 2 ) + ProgressiveMoladEPOCH
For example, again taking the ElapsedMonths( Rectify, 5766, Cheshvan ) = 71304 from above, the calculus-based progressive molad moment was about 732222.6161865. The fraction, when rounded to the nearest part, again corresponds to 14 hours 47 minutes and 6 parts. In this example the unrounded difference between the empirical and calculus-based progressive molad moments is about 2/3 second.
It is easy to non-empirically derive the inverse function for the calculus method, determining the Lunation number from a Talmudic Temporal Time moment (or from a rata die moment by first adding 1/4 day to the moment). Once the Lunation number is known, one can find any prior or subsequent progressive molad (mean lunar conjunction) simply by decrementing or incrementing the Lunation number as desired and then passing it back to the MoladMoment function in Rectify mode:
ProgressiveMomentToLunation( TTTmoment )
= ( SquareRoot( MSMatEpoch2 + 2 × MSMslope × ( TTTmoment – ProgressiveMoladEPOCH ) ) − MSMatEpoch ) / MSMslope
The returned Lunation number has a fractional part representing the elapsed portion of that mean lunation up to the given moment. Fractions equal to 1/4, 1/2, or 3/4 correspond to the mean first quarter, full moon, or last quarter, respectively. If desired, one can floor it to yield the integer Lunation number that started that mean lunar cycle, or round it to yield the closest integer Lunation number.
The calculus-based method, although theoretically sound, depends critically on the exact values employed for the MSMatEpoch and to a lesser extent the ProgressiveMoladEPOCH, which were derived by extrapolating 4000 years into the remote past before the starting Lunation that was employed for the perigee eclipse study. It might be wiser to integrate relative to a later epoch that is within the study period. The obvious choice is in the era of Hillel ben Yehudah, at the vertex of the parabola used for molad adjustment, that is at the Lunation number where the difference between the traditional molad and the mean lunar conjunctions was at a minimum. Therefore we define:
LunationAtVertex = 50834
VertexEpoch = MoladMoment( Rectify, LunationAtVertex ) = 127731.420447531
MSMatVertex = MSMatEpoch + MSMslope × LunationAtVertex = 29+241760094829/455640344640 = 29.5305941356444
Now we can re-define the calculus methods to integrate relative to (before or after) the vertex epoch:
LunationMinusVertex = ElapsedMonths( Rectify, hYear, hMonth ) – LunationAtVertex
VertexProgressiveMolad( LunationMinusVertex ) = VertexEpoch + LunationMinusVertex × (MSMatVertex + MSMslope × LunationMinusVertex / 2)
For example, using double-precision floating point calculation, the VertexProgressiveMolad for Lunation 71303 ≈ 732193.08560, which is the same as the ProgressiveMolad when expressed to the same precision. However the unrounded ProgressiveMolad moment was slightly more than 1/4 second later than the VertexProgressiveMolad moment. The inverse function for the vertex integration method is:
VertexProgressiveMomentToLunation( TTTmoment )
= LunationAtVertex + ( SquareRoot( MSMatVertex2 + 2 × MSMslope × ( TTTmoment – VertexEPOCH ) ) – MSMatVertex ) / MSMslope
Again, the returned Lunation number has a fractional part representing the elapsed portion of that mean lunation up to the given moment. Fractions equal to 1/4, 1/2, or 3/4 correspond to the mean first quarter, full moon, or last quarter, respectively. If desired, one can floor it to yield the integer Lunation number that started that mean lunar cycle, or round it to yield the closest integer Lunation number.
At this point you are probably wondering which function to use for the progressive molad, the empirical MoladMoment function in Rectify mode (based directly on the perigee eclipse study) or the derived alternate or vertex functions? Due to the limitations of double-point floating-point calculations, results returned by these 3 function variants may differ by a fraction of a second, which could rarely make a difference in the calendar arithmetic. This question deserves further evaluation — it is not just a question of which variant is more accurate, because at present there is no way to establish that with confidence, given the limitations of today’s astronomical algorithms and the uncertainty of future changes in the Earth rotation rate. Rather, the more important question is: Which method is the most reproducible and consistently yields the same results on different computer platforms? Would there be an advantage in using a modern epoch, such as J2000.0 (the astronomical favorite) for the calculus methods? For now, I retain all 3 definitions of the function because I believe that they have educational value, but designate the empirical MoladMoment function in Rectify mode as the official method for the progressive molad, whereas the VertexProgressiveMomentToLunation function is the method of choice for the inverse.
Some people like to know the clock time of the molad moment, perhaps to choose an auspicious moment for starting a significant life event after a new lunar cycle begins, or to know the earliest and latest time for saying the Kiddush Levanah prayer (blessing on the Moon, said once during the waxing phase of each lunar cycle, when Moon is clearly visible). In the case of the traditional molad, such thinking is at best misguided, because there is nothing particularly auspicious
about such a moment (due to the drift of the traditional molad with respect to the actual lunar conjunctions and the superimposed periodic variations of the duration of the lunar cycle), and anyhow there is no meaningful way to properly convert a traditional molad moment to a normal time-of-day (clock time). Even though I have shown that in the era of the Maccabees the traditional molad reference meridian was 16 minutes of time ahead of Jerusalem mean solar time, the molad moments have been drifting steadily later with respect to mean lunar conjunctions, in effect shifting the reference meridian progressively eastward at an accelerating rate. Thus one cannot define a ritually meaningful procedure to convert a traditional molad moment to a real date and time. In other words, although the traditional molad was most likely intended to represent the mean lunar conjunction moment, in actuality today it is only an arithmetic value used to determine the date of Rosh HaShanah, and it has no physical meaning that has any other valid ritual significance.
On the other hand, any progressive molad moment represents the actual secular mean lunar conjunction, referred to the meridian of Jerusalem (the word secular, derived from the Latin saeculum, in this context refers to a variation that spans centuries, that is the progressively shorter mean synodic month), and is directly convertible to a real date and time:
To convert a progressive molad moment to the Rectified Hebrew Calendar year and month that it corresponds to, add 3 days to the moment (to ensure that the working moment is on or after the first day of the month, because most progressive molad moments land on the day before the next month starts), then use FixedToHebrew in Rectify mode to convert that moment to a Rectified Hebrew year and month, but ignore the day number within the month.
To convert a progressive molad moment to the actual Rectified Hebrew Calendar date that it falls on, subtract 1/4 day to convert it to civil time (counting the hours from midnight), then directly use FixedToHebrew in Rectify mode to convert that moment to a Rectified Hebrew year, month, and day number within the month.
To convert a progressive molad moment to a Universal Time rata die moment, subtract the 2 hours and 21 minutes for the meridian difference from the Prime Meridian to Jerusalem, and also deduct 1/4 day to count the hours from midnight instead of sunset. Note, however, that after conversion the molad weekday will be one weekday too early for any molad moment between 18:00h (temporal time of sunset) and midnight, in other words it will have become a Universal Time civil weekday instead of a Hebrew weekday. The fraction of a day 167/480 = 8 hours and 21 minutes includes 2 hours and 21 minutes for Jerusalem Mean Solar Time, plus 1/4 day to convert the molad moment from Talmudic Temporal Time to Civil Time:
ProgressiveMoladToUniversal( ThisMolad ) = ThisMolad – 167/480
For the rectifed molad example given above, 732222.616194 – 167/480 = 732222.26828 = 06:26:19 UT.
Once the moment is in Universal Time, it can be easily converted to any zone clock time by adding the time zone number (in hours) as a fraction of a day:
UniversalToStandard( UTmoment, TimeZone ) = UTmoment + TimeZone / 24
For example, to convert the above moment to the Eastern Standard Time, as used in Toronto, where the time zone number is −5, corresponding to a standard clock time that is 5 hours behind UT, the above UT moment = 732222.26828 + ( −5) / 24 = 732222.0599 = 01:26:19 h EST on the same date. However, Daylight Saving Time was in effect on that date, so one must add one hour to obtain the zone clock time = 02:26:19 h.
After conversion to zone clock time the progressive molad moment is the moment of the actual secular mean lunar conjunction for that time zone. In the present era, however, due to the combination of periodic variations in the duration of lunations, individual actual lunar conjunctions can vary by up to ±14 hours from that mean moment. Nevertheless, if there is anything auspicious
about any molad moment, the progressive molad moment is the one to go by! (It seems to me that it would be better to obtain the actual moment of the true lunar conjunction, easily obtained from Kalendis, to be sure that the event begins after the start of the new lunar cycle.)
To find the previous or next progressive molad moment relative to a given zone clock moment, convert the zone clock time to a Universal Time moment by subtracting one hour if Daylight Saving Time is in effect, then subtract the time zone number. Then pass the UT moment to the JumpProgressiveMolad function, whose calling syntax is:
JumpedToMolad = JumpProgressiveMolad( UTmoment, PlusOrMinus )
where PlusOrMinus = −1 for the prior molad or +1 for the next molad
This function converts the UT moment to Jerusalem Mean Solar Time and then to Talmudic Temporal Time (counting the hours from the prior sunset), then finds the nearest Lunation number (if the given UTmoment is not near the mid-point between two progressive molad moments then this conversion makes no difference and the UTmoment can be used directly):
Lunation = round( ProgressiveMomentToLunation( UTmoment + 2/24 + 21/1440 + 1/4 ) )
Provisionally calculate the UT moment of this progressive molad moment:
NearestMolad = ProgressiveMoladToUniversal( MoladMoment( Rectify, Lunation ) )
Compare with the UT moment, but round to 3 decimal places to ignore insignificant arithmetic differences (we only care about the sign of the comparison):
Diff = sign( round( UTmoment − JumpToMolad, 3 ) )
Depending on the comparison, return the previous or next molad moment, or the nearest molad that we already calculated:
IF Diff = PlusOrMinus THEN
RETURN ProgressiveMoladToUniversal( MoladMoment( Rectify, Lunation + PlusOrMinus ) )
ELSE
RETURN NearestMolad
END IF
The JumpProgressiveMolad procedure given above returns the jumped-to molad moment as a Universal Time moment. Modify or convert to any other time zone as desired.
For example, to find the next progressive molad moment after the Traditional Hebrew Calendar date 25 Kislev 5766, the first day of one of the latest Chanukah celebrations in history (started on Gregorian December 26, 2005 — it occurs latest in the 9th year of each 19-year cycle, and was one day later in the 9th year of each of the previous 3 cycles because Cheshvan had 30 days), was rata die 732306. PlusOrMinus = +1, Lunation = 71307, NearestMolad ≈ 732310.86, Diff = – 1, which does not equal PlusOrMinus, so the NearestMolad is returned. To find the previous from the same date, PlusOrMinus = −1, Diff = −1, which equals PlusOrMinus, so the progressive molad of Lunation − 1 is returned ≈ 732281.33.
Comments and suggestions received to date, and their status with regard to changes of this document are separately tabulated on this page.
Updated 30 Shevat 5767 (Traditional) = 30 Shevat 5767 (Rectified) = February 20, 2007 (Symmetry454) = February 17, 2007 (Gregorian)