Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!tut.cis.ohio-state.edu!thurn From: thurn@cis.ohio-state.edu (Martin 'Sulu' Thurn) Newsgroups: comp.lang.pascal Subject: Re: day-of-week algorithm Message-ID: <59529@tut.cis.ohio-state.edu> Date: 1 Sep 89 17:32:50 GMT Sender: thurn@tut.cis.ohio-state.edu Lines: 86 I apologize if this has already been discussed, but I recently discovered a point of confusion / error (gasp!) in the day-of-week algorithm posted here several months ago. This article appeared last April (1989): >Article 1563 of comp.lang.pascal: >From: RDK%vm.temple.edu@cunyvm.cuny.edu (Robert Keiser) > >I have used the following algorithm to get the Day of week. It will work for >any date after 1800. In the following, Year is a 4 digit integer i.e. 1989 >not just the 89 part. > > N := 1461*f(year,month) / 4 + 153*g(month) / 5 + day > > where: > f(year,month) = year - 1 if month <= 2 > year otherwise > > g(month) = month + 13 if month <= 2 > month + 1 otherwise > > Then apply the following formula to N > dow = (N - 621,049) MOD 7 > > This formula was found in _Programming in ANSI C_ > by Stephen G. Kochan pg. 188 > >Robert Keiser >Bitnet : RDK@Templevm >Internet : RDK@vm.temple.edu (* the above formula returns 0 for saturday, 1 for sunday, ... 6 for friday. *) Without giving it much thought, (i.e. what the heck do these numbers mean?), I implemented (and modified) this in TurboPascal 5.0 as follows: function day_of_week(y,m,d:word): day; const f:array[monthrange] of integer=(-1,-1,0,0,0,0,0,0, 0, 0, 0, 0); g:array[monthrange] of byte= (14,15,4,5,6,7,8,9,10,11,12,13); var tempint:longint; begin { tempint := round( ((1461*(y+f[m])) / 4) + ((153 * g[m]) / 5) + d - 621049 ) MOD 7; ^^^^ my first attempt, gives trouble when (153*month) MOD 5 > 2 e.g. 1 sep 1989 } { tempint := ceiling( ((1461*(y+f[m])) / 4) + ((153 * g[m]) / 5) + d - 621049 ) MOD 7; ^^^^ my second attempt, gives trouble when (153*month) MOD 5 = 4 e.g. 1 dec 1989 } tempint := ( ceiling( (1461*(y+f[m])) / 4 + 0.01) + trunc((153 * g[m]) / 5) + d - 621049 ) MOD 7; { ^^^^ this one is perfect! (?) } if (tempint = 0) then tempint := 7; (* so sunday = 1, ... saturday = 7 *) day_of_week := day(tempint); end; So, notice that a correct (unless I missed something) version of this algorithm requires rounding up the year calculation (adding 1 if it comes out with no fractional part) and throwing out the fractional part of the month calculation. I don't know why this works, but it is based on an empirical test (and successfully finding calendars of 4 different years) of all 20 combinations of how the fractional parts of the year and month calculations turn out. If anyone is interested, I can e-mail my Quattro spreadsheet :-O On another note (which I didn't think about until after I had done all the dirty work), what the heck is this 621049 business? We're immediately taking MOD 7, so why not just subtract (621049 MOD 7) and be done with it? On anothother note: That year calculation turns out to be y * 365.25, which "makes sense" because every 4th year is a leap year. But what about every 400th year is NOT a leap year? Should there be a factor of /400ths in there somewhere? My mind is a bit too boggled at the moment, but I figure I have 10 years to figure it out. ---Martin Thurn thurn@cis.ohio-state.edu 73747.224@compuserve.com Disclaimer: The preceding statements are n...Wait a minute! I AM the company!