Newsgroups: comp.lang.dylan
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!news.sprintlink.net!EU.net!sun4nl!news.nic.surfnet.nl!ruu.nl!neuretc.biol.ruu.nl!user
From: reinder@neuretp.biol.ruu.nl (Reinder Verlinde)
Subject: Re: day of week algorithm
Message-ID: <reinder-2802951125550001@neuretc.biol.ruu.nl>
Sender: usenet@cc.ruu.nl
Organization: Rijksuniversiteit Utrecht
X-Newsreader: Value-Added NewsWatcher 2.0b22.0+
References: <3isptj$8hg@brtph500.bnr.ca> <RAIBLE.95Feb27170320@win57.nas.nasa.gov>
Date: Tue, 28 Feb 1995 10:25:55 GMT
Lines: 59

In article <RAIBLE.95Feb27170320@win57.nas.nasa.gov>, raible@nas.nasa.gov wrote:

> In article <3isptj$8hg@brtph500.bnr.ca> Ted Lowery <ted.lowery@nt.com> writes:
> 
>    Hi all-
> 
>    Anybody out there know the algorithm to calculate the day of the
>    week from a date.  I remember from college days there is a formula, 
>    but I cannot seem to find it.
> 
> You get extra points if you figure out how this works.
> I got the algorithm from John Conway (the mathematician)
> who can do the calculation for any arbitrary data in about
> a second or so.
> 
> - Eric
> 
> (define (day-of-week-for-last-day-in-feb year)
>   (if (< year 1900)
>     (error "Too early"))
>   (let* ((from-1900       (- year 1900))
>          (12-year-spans   (quotient from-1900 12))
>          (extra           (modulo from-1900 12))
>          (leap-year-count (quotient extra 4)))
>     (modulo (+ 12-year-spans
>                extra
>                leap-year-count
>                3) ; Feb 28, 1900 was a wednesday
>             7)))
> 
> (define (leap-year? year)
>   (if (zero? (modulo year 4))
>     (if (zero? (modulo year 100))
>       (zero? (modulo year 400))
>       #t)))
> 
> (define (same-day-as-last-day-in-feb month year)
>   (list-ref
>    (if (leap-year? year)
>      ; 1  2  3  4  5  6  7  8  9  10 11 12
>      '(4 29  7  4  9  6 11  8  5  10  7 12)
>      '(3 28  7  4  9  6 11  8  5  10  7 12))
>    (- month 1)))
> 
> (define (day-of-week month day-of-month year)
>   (let ((num1 (day-of-week-for-last-day-in-feb year))
>         (num2 (same-day-as-last-day-in-feb month year)))
>     (list-ref '(sun mon tue wed thu fri sat)
>               (modulo (+ 28
>                          (- day-of-month num2)
>                          num1)
>                       7))))

The algorithm in question is fully discussed in Conways 'Winning Ways'.
It also discusses its limits (i.e. discusses when the Gregorian calender
was used where), and gives a way to compute the date of Easter for years
up to _whatever_ year.

Reinder Verlinde
