_STRUCTURED PROGRAMMING COLUMN_ by Jeff Duntemann [LISTING ONE] FUNCTION Modulus(X,Y : Integer) : Integer; VAR R : Real; BEGIN R := X/Y; IF R < 0 THEN Modulus := X-(Y*Trunc(R-1)) ELSE Modulus := X-(Y*Trunc(R)); END; [LISTING TWO] PROGRAM ZelTest2; { From DDJ 11/90 } CONST DayStrings : ARRAY[0..6] OF STRING = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'); VAR Month, Day, Year : Integer; { This function implements true modulus, rather than } { the remainder function as implemented in MOD. } FUNCTION Modulus(X,Y : Integer) : Integer; VAR R : Real; BEGIN R := X/Y; IF R < 0 THEN Modulus := X-(Y*Trunc(R-1)) ELSE Modulus := X-(Y*Trunc(R)); END; 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! } Holder := Modulus(Holder,7); { Take Holder modulus 7 } { 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; BEGIN Write('Month (1-12): '); Readln(Month); Write('Day (1-31): '); Readln(Day); Write('Year : '); Readln(Year); Writeln('The day of the week is ', DayStrings[CalcDayOfWeek(Year,Month,Day)]); Readln; END.