[net.sources] bug in ``at'' leap-year calculation

fred@gymble.UUCP (08/10/84)

Here's a cute one which no one seems to have run into. (Gee, am I the
only person who uses ``at''?) Suppose you spool a command on August 9
to be executed on March 1. Since March 1 is an earlier date than August
9, at assumes you mean March 1 of  NEXT year. So far so good. At
schedules activities by julian date within the year (Jan 1 = 0),
ignoring months, and converts to this form immediately.

If the current year happens to be a leap-year and the julian date it
computes is greater than 59 (Feb 29) it adds one, to account for the
extra day, which shifts the julian dates for the rest of the year up by
one. Trouble is, it does this BEFORE checking to see whether to
increment the year (in which case the leap-year conversion for the NEXT
year should apply to the date), so if this year is a leap-year and the
next one isn't (When's the last time you saw two leap-years in a row?)
or the current year is not a leap-year and the next one is, and you
schedule something after February of the next year, it'll be executed
either a day early or late.

The fix for this bug (I'm convinced there are others.) is:

*** /usr/src/usr.bin/at.c (This the the 4.2BSD at.c.)
  	if (uday < today)
  		uyear++;
 	if (uyear%4==0 && uday>59) <---+--- add these two lines
 		uday += 1;	   <--/
  	c = uyear%4==0? 366: 365;
  	if (uday >= c) {
***************

***************
  		while(--found>=0)
  			uday += months[found].mlen;
  		if (detail->tm_year%4==0 && uday>59) <--+-- delete these
  			uday += 1; <-------------------/
  		return(3);
***************