xref: /minix3/usr.bin/cal/README (revision a99e83a2dc64913b9c73fdffb51d90f2b6a7b3e2)
1*a99e83a2SThomas CortThe cal(1) date routines were written from scratch, basically from first
2*a99e83a2SThomas Cortprinciples.  The algorithm for calculating the day of week from any
3*a99e83a2SThomas CortGregorian date was "reverse engineered".  This was necessary as most of
4*a99e83a2SThomas Cortthe documented algorithms have to do with date calculations for other
5*a99e83a2SThomas Cortcalendars (e.g. julian) and are only accurate when converted to gregorian
6*a99e83a2SThomas Cortwithin a narrow range of dates.
7*a99e83a2SThomas Cort
8*a99e83a2SThomas Cort1 Jan 1 is a Saturday because that's what cal says and I couldn't change
9*a99e83a2SThomas Cortthat even if I was dumb enough to try.  From this we can easily calculate
10*a99e83a2SThomas Cortthe day of week for any date.  The algorithm for a zero based day of week:
11*a99e83a2SThomas Cort
12*a99e83a2SThomas Cort	calculate the number of days in all prior years (year-1)*365
13*a99e83a2SThomas Cort	add the number of leap years (days?) since year 1
14*a99e83a2SThomas Cort		(not including this year as that is covered later)
15*a99e83a2SThomas Cort	add the day number within the year
16*a99e83a2SThomas Cort		this compensates for the non-inclusive leap year
17*a99e83a2SThomas Cort		calculation
18*a99e83a2SThomas Cort	if the day in question occurs before the gregorian reformation
19*a99e83a2SThomas Cort		(3 sep 1752 for our purposes), then simply return
20*a99e83a2SThomas Cort		(value so far - 1 + SATURDAY's value of 6) modulo 7.
21*a99e83a2SThomas Cort	if the day in question occurs during the reformation (3 sep 1752
22*a99e83a2SThomas Cort		to 13 sep 1752 inclusive) return THURSDAY. This is my
23*a99e83a2SThomas Cort		idea of what happened then. It does not matter much as
24*a99e83a2SThomas Cort		this program never tries to find day of week for any day
25*a99e83a2SThomas Cort		that is not the first of a month.
26*a99e83a2SThomas Cort	otherwise, after the reformation, use the same formula as the
27*a99e83a2SThomas Cort		days before with the additional step of subtracting the
28*a99e83a2SThomas Cort		number of days (11) that were adjusted out of the calendar
29*a99e83a2SThomas Cort		just before taking the modulo.
30*a99e83a2SThomas Cort
31*a99e83a2SThomas CortIt must be noted that the number of leap years calculation is sensitive
32*a99e83a2SThomas Cortto the date for which the leap year is being calculated.  A year that occurs
33*a99e83a2SThomas Cortbefore the reformation is determined to be a leap year if its modulo of
34*a99e83a2SThomas Cort4 equals zero.  But after the reformation, a year is only a leap year if
35*a99e83a2SThomas Cortits modulo of 4 equals zero and its modulo of 100 does not.  Of course,
36*a99e83a2SThomas Cortthere is an exception for these century years.  If the modulo of 400 equals
37*a99e83a2SThomas Cortzero, then the year is a leap year anyway.  This is, in fact, what the
38*a99e83a2SThomas Cortgregorian reformation was all about (a bit of error in the old algorithm
39*a99e83a2SThomas Cortthat caused the calendar to be inaccurate.)
40*a99e83a2SThomas Cort
41*a99e83a2SThomas CortOnce we have the day in year for the first of the month in question, the
42*a99e83a2SThomas Cortrest is trivial.
43