Time since the epoch

George Russell ger@tzi.de
Tue, 11 Feb 2003 18:23:49 +0100


Peter wrote (snipped)
> As far as I read ISO8601 (which also has a notation for durations)
> this is unspecifed :-) And as far as I read TimeExts.lhs it does some
> sort of rollover. My take would be to specify the behavior for adding
> something like a TimeDiff to a base date in a consistent manner and
> then cast that in stone. If there is a (reasonable) standard for this
> kind of calculation, then this should be the basis for the specification.
OK, what TimeExts does, I hope, is add the appropriate amount of the appropriate
time unit (whatever it is) directly, then rely on the CalendarTime conversions to
resolve any overflows.  This probably isn't very clear,
so I'll give some examples of what I think ought to happen.

Add 1 month to 1st February 2003.  This produces 1st March 2003.  (with no overflow.)

Add 1 month to 31st January 2003.  Then we get 31st February 2003.  This clearly requires
an overflow; we note that February 2003 has 28 days, and so roll over to 3rd March 2003.

Note that in this case "Add 1 month" is not a monotonic operation. 

Add 1 minute to 23:59:60 31st December 2003.  I assume that this is a valid time and that it
will be a leap second; if not choose some other year.

This is complicated since we have multiple overflows.  First stage you get the invalid time

23:60:60 31st December 2003.  I don't know what TimeExts (or rather the CalendarTime conversions)
do in this case, but what I think they *ought* to do is work from the most significant unit down,
rolling around to produce a significant date at each time.  When we roll around, we have to bump the
next unit, and iterate.

So:
2003 OK.
2003 December OK.
2003 December 31st OK.
2003 December 31st 23 OK.
2003 December 31st 23:60 NOT OK.  We bump the next unit and subtract this one, then we have to iterate
   from the top down.   So we replace 23:60 by 24:00.
   and get
2003 December 31st 24
   not OK.  Replaces "31st 24" by "32nd 00".
2003 December 32nd 
   not OK
2003 Unidecimber (13th month) 1st
   not OK
2004 January OK
2004 January 1st OK
2004 January 1st 00 OK
2004 January 1st 00:00 OK
2004 January 1st 00:00:60 Not OK.
   Replace 00:60 by 01:00 and you eventually get
2004 January 1st 00:01:00