Zeller

Paul Eggert eggert at twinsun.com
Wed Oct 4 17:45:15 UTC 2000


Oscar van Vlijmen <o.van.vlijmen at tip.nl> writes:

> Allow me to give a couple of key sources for Zeller's algorithm to find the
> day of the week:

I see that those source's formulas have diverged a bit from Zeller's
original algorithm, which you can find in:

Chr. Zeller, Kalender-Formeln, Acta Mathematica, Vol. 9, Nov. 1886

I haven't read the original article (I don't read German), but I have
seen a translation whose location escapes me now.  I think if you
translate his original formulas unchanged into C, and assume
nonnegative years, they would look like this:

  /* Calculcate weekday number for Gregorian date YYYY-MM-DD.  */
  int jan_or_feb = MM <= 2;
  int y = YYYY - jan_or_feb;
  int J = y / 100;     // century number
  int K = y % 100;     // year number within the same
  int m = MM + 12 * jan_or_feb;   // month number
  int q = DD;          // day number in the month
  int h = (q + ((m + 1) * 26) / 10 + K + K/4 + J/4 - 2*J) % 7;  
                       // weekday number (1 is Sunday)

However, this ignores overflows and doesn't handle negative years
correctly.  If you want it to work more generally, you need to alter
the formulas, e.g. to something like the following.  Please note that
I've written this code by hand just now without testing it, so it's
quite possibly buggy.

  #define DIV(a, b) (((a)/(b)) - ((a)%(b) < 0))
  int jan_or_feb = MM <= 2;
  int K1 = YYYY % 100;
  int K2 = K1 - (K1 == 0 & jan_or_feb);
  int J = YYYY / 100 - (K2 < 0);
  int K = (K2 + 100) % 100;
  int m = MM + 12 * jan_or_feb;
  int q = DD;
  int h1 = (q + ((m + 1) * 26) / 10 + K + DIV(K,4) + DIV(J,4) - 2*J) % 7;
  int h = (h1 + 6) % 7;



More information about the tz mailing list