comp.lang.ada
 help / color / mirror / Atom feed
From: Thomas Wolf <t_wolf@angelfire.com>
Subject: Re: Zeller's Algorithm
Date: Mon, 29 Jul 2002 10:29:09 +0200
Date: 2002-07-29T10:29:09+02:00	[thread overview]
Message-ID: <MPG.17af1b07795920d8989693@news.ip-plus.net> (raw)
In-Reply-To: 3D3F1C88.B430AC1F@lmco.com

paul.a.storm@lmco.com wrote:
> 
> I am still confused as to why the Zeller algorithm wouldn't work.  Since
> the algorithm has been
> around since 1875 I figure it has proven out.  Although I am still
> cogitating on whether it
> takes into account for centennial non-leap years(1800,1900, etc.) and
> quatra-centennial leap years(i.e. 2000).

Yes it does.

> It bugs me when I can't figure out the reason for some code not
> working.  Know what I mean?

Zeller's *algorithm* does work for dates in the Gregorian calendar.
It's just the poor, buggy *implementation* posted at AdaPower that
doesn't work.

> Did you try to compile the program from the link I gave and did you have
> any problems like I had?

No, I didn't try to run that program. It is flawed in two ways:

1. The "if Month < 3" stuff should be moved out of GetValidDate into
   UseZeller.
2. UseZeller shouldn't add 1 at the end.

For a working implementation of Zeller's algorithm, try this:

   type Weekday is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
   --  ISO starts the week on a monday, so let's do the same here...

   function Day_Of_Week
     (Date : in Ada.Calendar.Time)
     return Weekday
   is
     --  Returns the day of the week. Works for dates of the 
     --  Gregorian calendar.

      Day   : Ada.Calendar.Day_Number;
      Month : Ada.Calendar.Month_Number;
      Year  : Ada.Calendar.Year_Number;
      Secs  : Ada.Calendar.Day_Duration;

      M, Y, Century, Z : Integer;

   begin
      --  This is Zeller's formula.
      Ada.Calendar.Split (Date, Year, Month, Day, Secs);
      if Month < 3 then
         M := Integer (Month) + 10;
         Y := Integer (Year) - 1;
      else
         M := Integer (Month) - 2;
         Y := Integer (Year);
      end if;
      Century := Y / 100; Y := Y mod 100;
      Z :=
        (Integer (Day) + (13 * M - 1) / 5 + Y + Y / 4 +
         Century / 4 - 2 * Century) mod 7;
      --  The left operand of the "mod" may be negative, but "mod 7"
      --  does the right thing and gives us a positive remainder in
      --  the range 0 .. 6.
      --  
      --  Now 0 is Sunday, 1 is Monday, and so on. Map this such that
      --  0 is Mon, 1 is Tue, and 6 is Sun.
      return Weekday'Val ((Z + 6) mod 7);
   end Day_Of_Week;

I'll make available this function in a future release of
my Util subsystem.

-- 
-----------------------------------------------------------------
Thomas Wolf                          e-mail: t_wolf@angelfire.com




  reply	other threads:[~2002-07-29  8:29 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-23 23:56 Zeller's Algorithm Paul A Storm
2002-07-24  7:59 ` Thomas Wolf
2002-07-24 21:30   ` Paul A Storm
2002-07-29  8:29     ` Thomas Wolf [this message]
2002-07-30  4:35       ` Robert Dewar
2002-07-30  8:20         ` Thomas Wolf
2002-07-30 17:17 ` Rick Maffei
2002-07-30 22:10   ` Paul A Storm
2002-07-31 10:51     ` Thomas Wolf
2002-07-31 14:33       ` Frank J. Lhota
2002-07-31 19:13         ` Robert A Duff
2002-07-31 19:26           ` Darren New
2002-07-31 20:01             ` Hyman Rosen
2002-07-31 20:15               ` Frank J. Lhota
2002-07-31 21:08               ` Robert A Duff
2002-07-31 22:34                 ` Hyman Rosen
2002-07-31 22:57                   ` Robert A Duff
2002-08-01 15:17                     ` Hyman Rosen
2002-08-01 16:41                       ` Frank J. Lhota
2002-07-31 21:15               ` Dan Nagle
2002-07-31 22:36                 ` Hyman Rosen
2002-07-31 22:23         ` Matthew Woodcraft
2002-08-02  7:21         ` Thomas Wolf
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox