Martin Smoot msmoot at nssolutions.com
Wed Oct 4 18:41:05 UTC 2000

The following C code is believed to work correctly for all reasonable
cases (if it does not work in 1000 years - sorry - dig me up and I will
fix it) and is copied directly from our software and was written
following the Zeller algorithm described in a book written by Terry
Dollhoff back in 1980 (I belive that the title was "16 Bit
Microprocessor Architecture" and publisher was Reston Publishing but if
anybody needs exact information, I will find the book at home).  the
book gave this as an example for doing fixed point arithmetic (since
floating point was not usually available in the micro world back then)
and I modified it to be all integer instead.

The "DTB" structure declaration is not included but should be of a
pretty obvious format based on the field names.

/* set_day_of_week - Set day of week from valid DTB.			*/

Zellers Congruence Data

automatically calculate the day of the week
from the entered date.

static int zmonth_base[12] = {2,5,0,3,5,1,4,6,2,4,0,3};
void set_day_of_week(DTB *dtb)
	int zmonth;
	int zyear;
	int zcentury;

	zmonth=dtb->month-2-1; /* march=0 for this formula */

	The Zellers Congruence returns a zero based number for the
	day of the week.

	dtb->wkday = zmonth_base[zmonth] + dtb->day + zyear + (zyear/4)
	            - 2*zcentury+(zcentury/4);

	dtb->wkday= (dtb->wkday%7) + 1;	/* dtb.wkday is one based (1=sunday) */
	if(dtb->wkday<=0) dtb->wkday+=7;

The last line in the routine was added because this implementation
failed to handle Saturday correctly starting in March this year (because
the wkday field is 1 based).  this may be why several examples I have
seen add 77 (or othersome other multiple of 7) in the calculation
because the wkday field would otherwise become negative on Saturday
which messes things up a bit.
Martin Smoot
Network Storage Solutions
msmoot at nssolutions.com         www.nssolutions.com

More information about the tz mailing list