Zeller's Congruence Script Bombs
Author Message
Zeller's Congruence Script Bombs

This program uses Zeller's Congruence to calculate the Day of the Week.
I grabbed it off the net a while back.  It has been working fine,
but I now see that it bombs on January and February--can anyone help?

AtG> dayofweek 1994 1 1
Sun
AtG> dayofweek 1994 2 1
Sun
AtG> dayofweek 1994 3 1
Tue
AtG> cal 1994
1994

Jan                    Feb                    Mar
S  M Tu  W Th  F  S    S  M Tu  W Th  F  S    S  M Tu  W Th  F  S
1          1  2  3  4  5          1  2  3  4  5
2  3  4  5  6  7  8    6  7  8  9 10 11 12    6  7  8  9 10 11 12
9 10 11 12 13 14 15   13 14 15 16 17 18 19   13 14 15 16 17 18 19
16 17 18 19 20 21 22   20 21 22 23 24 25 26   20 21 22 23 24 25 26
23 24 25 26 27 28 29   27 28                  27 28 29 30 31
30 31

#!/usr/usc/bin/perl

# Summary: zeller's congruence
# Keywords: weekday perl subroutine
# Date: 2 Oct 90 17:21:14 GMT
# Organization: Advanced Micro Devices; Sunnyvale, CA
#
# Here's a simple subroutine to calculate Day of the Week using
# Zeller's Congruence, which I've found very useful.  A lot of
# the temporary variables could be omitted by making it harder to read.

# usage: zeller yyyy mm dd
unless (\$#ARGV == 2) {
print STDERR "Usage: \$0 yyyy mm dd\n";
exit 1;

Quote:
}

print \$day,"\n";

sub weekday {

local(\$y,\$m,\$c,\$yy,\$z);

\$y = \$year;
\$m = (\$month + 10) % 12;
\$y-- if (\$m > 10);
\$c = int ( \$y / 100 );
\$yy = \$year % 100;

\$z = (  int ( (26*\$m - 2)/10) + \$day + \$yy + int(\$yy/4) +
int (\$c/4) - 2 * \$c ) % 7;
return \$wday[\$z];

Quote:
}

Thanks,

University Computing Services                      UUCP: ...!usc!neilson

PHONE: (213) 740-2693

--

University Computing Services                      UUCP: ...!usc!neilson

PHONE: (213) 740-2693

Thu, 27 Jun 1996 12:47:02 GMT
Zeller's Congruence Script Bombs

Quote:
>  This program uses Zeller's Congruence to calculate the Day of the Week.
>I grabbed it off the net a while back.  It has been working fine,
>but I now see that it bombs on January and February--can anyone help?

...
>        \$y = \$year;
>        \$m = (\$month + 10) % 12;
>        \$y-- if (\$m > 10);
>        \$c = int ( \$y / 100 );
>        \$yy = \$year % 100;

^^^^^^^^^^^^^^^^^^
Quote:

>        \$z = (  int ( (26*\$m - 2)/10) + \$day + \$yy + int(\$yy/4) +
>            int (\$c/4) - 2 * \$c ) % 7;
>        return \$wday[\$z];

...

o   As I understand the algorithm, it treats January and February as the
last two months of the preceding year.  In the above code, \$y and \$m

\$c and \$yy are then the century and the year within the century.  These
should be computed from the adjusted year.  \$c was, but \$yy wasn't!
If you change the indicated line to
\$yy = \$y % 100;
you should get the right answers in January and February (the only time
of year when the adjusted year and the actual year are different).

o   As I remember it, the man's name was pronounced "zeller" but _spelled_
Zoeller.

Sun, 30 Jun 1996 01:18:52 GMT
Zeller's Congruence Script Bombs

Quote:
>   This program uses Zeller's Congruence to calculate the Day of the Week.
> I grabbed it off the net a while back.  It has been working fine,
> but I now see that it bombs on January and February--can anyone help?
> ....
> sub weekday {

>         local(\$y,\$m,\$c,\$yy,\$z);

>         \$y = \$year;
>         \$m = (\$month + 10) % 12;

^^^^^^^^^^^^^^^^^^^^^^^^ WRONG!

Quote:
>         \$y-- if (\$m > 10);
>         \$c = int ( \$y / 100 );
>         \$yy = \$year % 100;

>         \$z = (  int ( (26*\$m - 2)/10) + \$day + \$yy + int(\$yy/4) +
>            int (\$c/4) - 2 * \$c ) % 7;
>         return \$wday[\$z];
> }

The problem is in the computation of the adjusted month.  Zellers
Congruence is based the old calendar, where the year begins in March
(hence September was the nineth month and October the tenth).
Thus, January and February are considered to be the eleventh and
twelfth months of the preceding year.

Unfortunately, the expression above yields the numbers 11 and 0 for
January and February, rather than 11 and 12 as it should.  The
following expression should yield the correct results:

\$m = (\$month + 9) %+12 - 1;

It would appear that the original author forgot to make the month
zero-based before doing modulo arithmetic on it.  I.e., the
expression is really:

\$m = ((\$month - 1) + 10) % 12 + 1;

The rest of the algorithm appears to be correct.

--
Gary Puckering                             Cognos Incorporated
VOICE:     (613) 738-1338 x3374          P.O. Box 9707

Mon, 01 Jul 1996 00:31:59 GMT

 Page 1 of 1 [ 3 post ]

Relevant Pages