Wednesday, March 20, 2013

[kvvqodny] Complete Gregorian calendar cycle

Here is a list of all 146097 dates, including the day of the week, of the 400-year Gregorian calendar cycle.  (Text file compressed with XZ.)  With it, one can easily verify, with grep, curious facts like the 13th of a month being most likely to fall on a Friday.  Or look up your birthday to see what day of the week you were born, adding a multiple of 400 years as necessary.

Also included is the Haskell computer program which generated the list.  As an exercise, instead of using Zeller's Congruence, the function gregorianTomorrow increments a date by one day, then we iterate that for 400 years.  The only tricky bit is the computation of the number of days in February:

lastDayOfMonth = Day $ if
elem m thirtyDayMonths then 30
else if m /= February then 31
else case mod y 4 of {
  0 -> case mod y 100 of {
    0 -> case mod y 400 of {
      0 -> 29;
      _ -> 28;
      };
    _ -> 29;
    };
  _ -> 28;
  };

1 comment:

Jedaï said...

I think it may be clearer as :

n `divide` m = m `mod` n == 0
isBissextile y = 4 `divide` y && not (100 `divide` y) || 400 `divide` y

lastDayOfMonth
| m `elem` thirtyDayMonths = 30
| m /= February = 31
| isBissextile y = 29
| otherwise = 28