mirror of
https://github.com/freebsd/freebsd-src
synced 2024-11-05 18:22:52 +00:00
42 lines
2.2 KiB
Text
42 lines
2.2 KiB
Text
The cal(1) date routines were written from scratch, basically from first
|
|
principles. The algorithm for calculating the day of week from any
|
|
Gregorian date was "reverse engineered". This was necessary as most of
|
|
the documented algorithms have to do with date calculations for other
|
|
calendars (e.g. julian) and are only accurate when converted to gregorian
|
|
within a narrow range of dates.
|
|
|
|
1 Jan 1 is a Saturday because that's what cal says and I couldn't change
|
|
that even if I was dumb enough to try. From this we can easily calculate
|
|
the day of week for any date. The algorithm for a zero based day of week:
|
|
|
|
calculate the number of days in all prior years (year-1)*365
|
|
add the number of leap years (days?) since year 1
|
|
(not including this year as that is covered later)
|
|
add the day number within the year
|
|
this compensates for the non-inclusive leap year
|
|
calculation
|
|
if the day in question occurs before the gregorian reformation
|
|
(3 sep 1752 for our purposes), then simply return
|
|
(value so far - 1 + SATURDAY's value of 6) modulo 7.
|
|
if the day in question occurs during the reformation (3 sep 1752
|
|
to 13 sep 1752 inclusive) return THURSDAY. This is my
|
|
idea of what happened then. It does not matter much as
|
|
this program never tries to find day of week for any day
|
|
that is not the first of a month.
|
|
otherwise, after the reformation, use the same formula as the
|
|
days before with the additional step of subtracting the
|
|
number of days (11) that were adjusted out of the calendar
|
|
just before taking the modulo.
|
|
|
|
It must be noted that the number of leap years calculation is sensitive
|
|
to the date for which the leap year is being calculated. A year that occurs
|
|
before the reformation is determined to be a leap year if its modulo of
|
|
4 equals zero. But after the reformation, a year is only a leap year if
|
|
its modulo of 4 equals zero and its modulo of 100 does not. Of course,
|
|
there is an exception for these century years. If the modulo of 400 equals
|
|
zero, then the year is a leap year anyway. This is, in fact, what the
|
|
gregorian reformation was all about (a bit of error in the old algorithm
|
|
that caused the calendar to be inaccurate.)
|
|
|
|
Once we have the day in year for the first of the month in question, the
|
|
rest is trivial.
|