SCCS-vsn: usr.bin/cal/README 5.2
-Program Design
-
-This program exactly duplicates the operation of the original unix "cal"
-program. It was designed with that intent, so no "improvements" were made
-to either the command line syntax or to the error reporting. The main
-goal was to allow replacement of the existing binary with a freely
-redistibutable version without breaking any existing applications that
-might be built on top of the original.
-
-The date routines were written from scratch, basically from first
+The cal(1) date routines were written from scratch, basically from first
principles. The algorithm for calculating the day of week from any
principles. The algorithm for calculating the day of week from any
-gregorian date was "reverse engineered". This was necessary as most of
+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.
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.
-I take 1 jan 1 to be 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:
+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
calculate the number of days in all prior years (year-1)*365
add the number of leap years (days?) since year 1
just before taking the modulo.
It must be noted that the number of leap years calculation is sensitive
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
+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
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
+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
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. Running diff on any output of this program and the
-equivalent output from the original cal reports no difference. This was
-confirmed by a script that ran them for all possible inputs (and took
-approximately 36 hours to complete on a sun-3.)