[sci.math] perpetual calendar

Robert_A_Freed@cup.portal.com (02/08/88)

In article <1217@mtuxo.UUCP> khreb@mtuxo.UUCP (01274-K.ROSEN) writes
to sci.math:

>The day of the week of day k, of month m (where a year is
>considered to start in March, so that March is month 1 of that year and
>January is considered the 11th month of the previous year and
>February the twelfth month of that year), of year
>100C + Y, where C is the century and Y is the year of the
>century, is given by the remainder of
>
>      k + [2.6m - 0.2] - 2C + Y  + [Y/4] + [C/4]
>
>when divided by 7, where Sunday is represented by a remainder of 0,
>Monday by 1, etc.
>
>For instance, for January 1, 1900 we have C=18, Y=99, m=11, and k=1
>(since January is considered the 11th month of 1899 for this
>calculation).   The formula becomes 1+28-36+99+4+24 which leaves a
>remainder of 1 when divided by 7.  Hence this day was a Monday.
>
>For a derivation of this formula see my book ELEMENTARY NUMBER THEORY
>AND ITS APPLICATIONS, Addison-Wesley, either first edition 1984 or
>the new second edition, 1988.  The formula is messy because of the
>problem of different numbers of days in months and leap years occurring
>every 4 years, except for even century years not divisible by 400.
>
>                                 Ken Rosen, AT&T
>                                 201-957-3691

(A similar, but slightly less elegant, formula was recently discussed in
comp.sys.ibm.pc as well.)

I believe this is known as Zeller's congruence.  It's also cited in the
text book, Elementary_Number_Theory, by Uspensky and Heaslet.  I first 
noticed this little gem in a 1965 book, Problems_for_Computer_Solution, 
by Fred Gruenberger and George Jaffray.  (The subject computer was the 
IBM 1620.  If that doesn't date me, I don't know what will! :-)

Two small comments about the above formula:

1.  [2.6m - 0.2] can be calculated as [(13m - 1)/5] to avoid the 
    overhead (and possible inaccuracy) of floating-point arithmetic.
    (Although not stated in the formulation, the square brackets [...]
    imply integer truncation.)

2.  This applies only to the current (Gregorian) calendar, which was
    established October 15, 1582, but was not adopted by Great Britain
    (and the American colonies) until 1752.

The formula is particularly efficient for computer solution since it 
involves only short integer arithmetic and a single conditional test 
(for January-February).  And, unlike many other day-of-the-week 
solutions I've seen, this one handles non-leap century years (such as 
1900 and 2100) correctly.

Bob Freed            Internet:  Robert_A_Freed@cup.portal.com
Newton Centre, MA        UUCP:  sun!portal!cup.portal.com!Robert_A_Freed

ags@j.cc.purdue.edu (Dave Seaman) (02/12/88)

In article <8802101656.AA08424@decwrl.dec.com> fulton@navion.dec.com (10-Feb-1988 0957) writes:

 [ description of perpetual calendar formula omitted ]

>        I have been intrigued by the above formula, and I coded it up in
>        Logitech Modula-2 to try it out.  It appears that there are some
>        cases where it doesn't work quite right.  For instance:

 [ example leading to negative numbers omitted ]

>        Then you have -1 MOD 7  =>  -1,  which does not equate to any of
>        the numbers assigned to Sunday thru Saturday, namely 0 thru 6. 

 [ illustration of adding 7 to make result positive ]
 
>        I guess that  this  is  an  after-the-fact  kludge;  perhaps the
>        original formula could be  changed  so  that  the result doesn't
>        require "fixing" if it comes out negative.

I don't have my copy of the Modula-2 standard available at the moment, but
I believe that the definition of the MOD operator is similar to Pascal,
where the standard says:

	A term of the form i mod j shall be an error if j is zero or
	negative, otherwise the value of i mod j shall be that value of
	(i-(k*j)) for integral k such that 0 <= i mod j < j.

Therefore the correct value of (-1 MOD 7) is 6, not -1.  In fact, I believe
that in Modula-2 the result of the MOD operator is type CARDINAL and
therefore cannot be negative.  It sounds as if you may be stuck with a
flawed implementation of Modula-2.

-- 
Dave Seaman	  					
ags@j.cc.purdue.edu

firth@sei.cmu.edu (Robert Firth) (02/12/88)

In article <6413@j.cc.purdue.edu] ags@j.cc.purdue.edu.UUCP (Dave Seaman) writes:

]I don't have my copy of the Modula-2 standard available at the moment, but
]I believe that the definition of the MOD operator is similar to Pascal,
]where the standard says:
]
]	A term of the form i mod j shall be an error if j is zero or
]	negative, otherwise the value of i mod j shall be that value of
]	(i-(k*j)) for integral k such that 0 <= i mod j < j.
]
]Therefore the correct value of (-1 MOD 7) is 6, not -1.  In fact, I believe
]that in Modula-2 the result of the MOD operator is type CARDINAL and
]therefore cannot be negative.  It sounds as if you may be stuck with a
]flawed implementation of Modula-2.

Well, I DO have my copy of the reference document [PIM-2, 3rd ed], and it
says no such thing.

Section 8.2 says, in particular

(a) the result of MOD is CARDINAL iff both operands are CARDINAL, and
    otherwise is INTEGER

(b) x MOD y is the remainder after DIV, ie y*(x DIV y) + x MOD y = y

(c) x DIV y is equal to the truncated quotient of x/y

Therefore, the correct value of -1 MOD 7, at least according to Wirth, is -1.