**[**Back to DATETIME SWAG index**]** **[**Back to Main SWAG index**]** **[**Original**]**

*{
EARL DUNOVANT
> Which date is what day For a particular month.
Zeller's Congruence is an algorithm that calculates a day of the week given
a year, month and day. Created in 1887(!). Jeff Duntemann of PC Techniques
fame implemented it in TP in the 11/90 issue of Dr Dobbs Journal, With a
(115 min left), (H)elp, More? major kludge because TP's MOD operator returns a remainder instead of a
True mathematical modulus. I added the Kludge Alert banner that I use in my
own code.
}
***Function **CalcDayOfWeek(Year, Month, Day : Integer) : Integer;
**Var
**Century,
Holder : Integer;
**begin
***{ First test For error conditions on input values: }
***if **(Year < 0) **or **(Month < 1) **or **(Month > 12) **or **(Day < 1) **or **(Day > 31) **then
**CalcDayOfWeek := -1 *{ Return -1 to indicate an error }
***else
***{ Do the Zeller's Congruence calculation as Zeller himself }
{ described it in "Acta Mathematica" #7, Stockhold, 1887. }
***begin
***{ First we separate out the year and the century figures: }
*Century := Year **div **100;
Year := Year **MOD **100;
*{ Next we adjust the month such that March remains month #3, }
{ but that January and February are months #13 and #14, }
{ *but of the previous year*: }
***if **Month < 3 **then
begin
**Inc(Month, 12);
**if **Year > 0 **then
**Dec(Year, 1) *{ The year before 2000 is }
***else ***{ 1999, not 20-1... }
***begin
**Year := 99;
Dec(Century);
**end**;
**end**;
*{ Here's Zeller's seminal black magic: }
*Holder := Day; *{ Start With the day of month }
*Holder := Holder + (((Month + 1) * 26) **div **10); *{ Calc the increment }
*Holder := Holder + Year; *{ Add in the year }
*Holder := Holder + (Year **div **4); *{ Correct For leap years }
*Holder := Holder + (Century **div **4); *{ Correct For century years }
*Holder := Holder - Century - Century; *{ DON'T KNOW WHY HE DID THIS! }
{***********************KLUDGE ALERT!***************************}
***While **Holder < 0 **do ***{ Get negative values up into }
*Inc(Holder, 7); *{ positive territory before }
{ taking the MOD... }
*Holder := Holder **MOD **7; *{ Divide by 7 but keep the }
{ remainder rather than the }
{ quotient }
{***********************KLUDGE ALERT!***************************}
{ Here we "wrap" Saturday around to be the last day: }
***if **Holder = 0 **then
**Holder := 7;
*{ Zeller kept the Sunday = 1 origin; computer weenies prefer to }
{ start everything With 0, so here's a 20th century kludge: }
*Dec(Holder);
CalcDayOfWeek := Holder; *{ Return the end product! }
***end**;
**end**;

**[**Back to DATETIME SWAG index**]** **[**Back to Main SWAG index**]** **[**Original**]**