xref: /csrg-svn/usr.bin/cal/README (revision 48367)
1*48367SbosticThe cal(1) date routines were written from scratch, basically from first
239233Sbosticprinciples.  The algorithm for calculating the day of week from any
3*48367SbosticGregorian date was "reverse engineered".  This was necessary as most of
439233Sbosticthe documented algorithms have to do with date calculations for other
539233Sbosticcalendars (e.g. julian) and are only accurate when converted to gregorian
639233Sbosticwithin a narrow range of dates.
739233Sbostic
8*48367Sbostic1 Jan 1 is a Saturday because that's what cal says and I couldn't change
9*48367Sbosticthat even if I was dumb enough to try.  From this we can easily calculate
10*48367Sbosticthe day of week for any date.  The algorithm for a zero based day of week:
1139233Sbostic
1239233Sbostic	calculate the number of days in all prior years (year-1)*365
1339233Sbostic	add the number of leap years (days?) since year 1
1439233Sbostic		(not including this year as that is covered later)
1539233Sbostic	add the day number within the year
1639233Sbostic		this compensates for the non-inclusive leap year
1739233Sbostic		calculation
1839233Sbostic	if the day in question occurs before the gregorian reformation
1939233Sbostic		(3 sep 1752 for our purposes), then simply return
2039233Sbostic		(value so far - 1 + SATURDAY's value of 6) modulo 7.
2139233Sbostic	if the day in question occurs during the reformation (3 sep 1752
2239233Sbostic		to 13 sep 1752 inclusive) return THURSDAY. This is my
2339233Sbostic		idea of what happened then. It does not matter much as
2439233Sbostic		this program never tries to find day of week for any day
2539233Sbostic		that is not the first of a month.
2639233Sbostic	otherwise, after the reformation, use the same formula as the
2739233Sbostic		days before with the additional step of subtracting the
2839233Sbostic		number of days (11) that were adjusted out of the calendar
2939233Sbostic		just before taking the modulo.
3039233Sbostic
3139233SbosticIt must be noted that the number of leap years calculation is sensitive
32*48367Sbosticto the date for which the leap year is being calculated.  A year that occurs
3339233Sbosticbefore the reformation is determined to be a leap year if its modulo of
34*48367Sbostic4 equals zero.  But after the reformation, a year is only a leap year if
35*48367Sbosticits modulo of 4 equals zero and its modulo of 100 does not.  Of course,
36*48367Sbosticthere is an exception for these century years.  If the modulo of 400 equals
37*48367Sbosticzero, then the year is a leap year anyway.  This is, in fact, what the
3839233Sbosticgregorian reformation was all about (a bit of error in the old algorithm
3939233Sbosticthat caused the calendar to be inaccurate.)
4039233Sbostic
4139233SbosticOnce we have the day in year for the first of the month in question, the
42*48367Sbosticrest is trivial.
43