[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Try this on your Symbolics

    Date: Tue, 4 Feb 1992 12:33 EST
    From: readingj@CERF.NET (John D. Reading)

    BTW^2:  I know about leap days and centuries - I just think this
    is a strange way to handle the problem.

It has nothing to do with centuries, although it does have to do with
leap days.

Here's the form that causes the trouble (in

  (when (>= secs *four-year-cycle*)
    (decf secs (* (floor secs *four-year-cycle*) *seconds-in-day*)))

It has the same result for secs = (* 86400 (+ (* (* 4 days) 365) days))
and (* 86400 (+ (* 4 days 365) (1- days))), for all integral values of
days.  You happened to notice it for days=25, which made (* 4 days) =>
100, so it looked like a century problem.  But the failure shows up with
the following minimal case:

(loop for days from 0 to 1 do
  (format t "~&~\\time-interval\\~%" (+ (* 4 365 86400) (* days 86400))))
4 years
4 years

The problem is that the above form is subtracting off the leap days
(TIME:*FOUR-YEAR-CYCLE* includes a leap day) so it can do the rest of
the computation assuming years are exactly 365 days long.  The other
number of the pair already has one day subtracted off, which puts it
into the previous four year cycle, so one less leap day is subtracted,
resulting in the same number of 365-day years.

Here's another anomoly:
(loop for years from 0 to 4 do
  (format t "~&~\\time\\~%" 
	  (+ (get-universal-time)
	     (time:parse-interval-or-never (format nil "~D years" years)))))
2/04/92 15:33:55
2/03/93 15:33:56
2/03/94 15:33:56
2/03/95 15:33:56
2/04/96 15:33:56

The underlying problem is that the length of the interval "1 year" is
dependent on which year, but the time interval routines don't know what
year.  Ignoring the century year exceptions, the length of the interval
"4 years" is constant (it's (1+ (* 4 365)) days), so the interval
routines correct every four years.  But this causes the discontinuity
you noticed.

The alternative is not to add the leap day correction.  But this would
cause (time:print-universal-time (+ (get-universal-time)
(time:parse-interval-or-never "100 years"))) to print a date in early
January, as all the leap days would be lost.