2004.11.01

 

Calculating the Gregorian number for a given date

by Karel Thönissen

If you are interested in calendar math and want to develop the ability to calculate the day of the week for any given date, I present these postings I did here. With a little math and a little exercise it should be possible to determine the day of the week mentally within a few seconds:


[parts of discussion snipped]


Your little algorithm is too simple, because you assume that January 1st is the first day of the calendar. It is not. The first day of the year is March 1st.

You missed the fact that the number of leap years (or actually: days), between to given years, depends on whether the days of the year are before or on/after March 1st.

What you should do is normalise the Gregorian dates to a calendar that starts on March 1st (like the Julian calendar did originally, hence the leap day at the end of the year).

For those who are interested to know: historically the leap day is not on February 29, but February 23rd (excuse my possible off-by-one error). Not that it makes any difference for your question, but it is a good Triviant-question.

 
[parts of discussion snipped]
 
 
I wrote 'first day of the calendar', not 'first day of the year'. An important difference.

Taking January 1st as the start of the year is a modern convention introduced some places as late as the 18th century. I think the start of the year used to be celebrated in England as 'Mayday'. The names of the months still provide a clue as does the position of the leap day. More information via Google. If you use broadband I can email you the paperback with the details (in Dutch).

Calendar calculations are greatly simplified if the date is first normalised to a calendar that starts on March 1st. Then there is even a regularity in the number of days in each month. The calculation becomes so simple that I can mentally calculate the day of the week of any date using these normalised dates.
 

[parts of discussion snipped]


Forget directly calculating the difference in days. Just calculate the Gregorian numbers for both dates and subtract these.

To give you an indication how to do this (I do not have the complete algorithm at hand):

function gregorian(yy, mm, dd: Int) return Int
   --
   -- first normalise the input
   -- then calculate the Julian number
   -- then make correction to obtain Gregorian number
   --
    if mm< 3
    then m2 := mm+9; y2 := yy-1
    else m2 := mm-3; y2 := yy

    julian: Int := int(y2*365.25)+int(m2*30.6+0.5)+dd
    return julian - correctionForEvery100and400yrs + calibration

If well-calibrated, the function returns 1 for the first date of the Gregorian calendar, i.e. 0001.03.01.

Now do not ask me to give you the inverse of this function (-8.