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

Re: [Scheme-reports] [r6rs-discuss] Date and time arithmetic library proposal for R7RS large Scheme

> From: John Cowan <cowan@x>
> WG2 has decided to include a date-time arithmetic
> library in R7RS large Scheme, and I just finished
> writing up an API proposal for one.  I decided to go
> for thorough rather than simple this time, and so I'm
> soliciting comments on it from sources outside WG2.
> The writeup is at
> http://trac.sacrideo.us/wg/wiki/TimeAdvancedCowan .
> Please use Reply All for your comments.  Thanks.

You say:

> an instant is a rational number representing a particular
> millisecond (or fraction thereof)

If fractions are allowed, why count milliseconds?
Just count seconds.  If milliseconds are needed,
multiply by 1000.

You say:

> of the Posix epoch

What does Posix have to do with a language that
may be implemented on any OS?  Use UTC.

In particular, Posix torques up leap seconds.

Trying to put both time-and-date *and* precise
sub-second intervals into one number is a loser.

In particular, does the current "instant"
increment uniformly, or does it encode the
current date?  It can not do both, and it
is unclear which you intend.

My proposal:

(time-of-day) - As close as possible to the UTC time
encoded as an integer.  It is incremented by 1 each
ordinary (non-leap) second.

It may or may not be incremented when a leap second
passes.  If it is not incremented then the same number
will be given to the leap second as to the preceding
second.  In other words, sometimes the time is 23:59:59
for two seconds before the new year arrives.  This
ambiguity is the price of encoding the time-of-day as a
single integer.

The time-of-day may be incremented each second without
knowing whether or not it is a leap second.

Alternatively, it may be incremented only at the start
of non-leap seconds, thus better tracking UTC.  This is
the preferred option.

(tick-count) - An integer that is incremented at
regular intervals as quickly as possible consistent
with regularity.  This number will never decrease while
the program is running, but may be changed arbitrarily
when the system is re-booted or equivalent.

(ticks-per-second) - The tick rate of the above
counter.  This number does not change, but may differ
from system to system.

(epoch-of-zero-ticks) - the second, in time-of-day
form, at the beginning of which the tick-count 
was zero.  (extrapolated, the tick-count
need not actually have been zero, indeed the
computer need not have yet been built)

>From these data, the date and the time of day can be
quickly computed with one second accuracy simply by
calling (time-of-day).  (But it will be off by one
second for each time the implementation fails to
non-count a leap second.)

The time interval between two events while the program
is running is:

(let ((start (tick-count)))
  (/ (- (tick-count) start) (ticks-per-second)))

and a sub-second timer that survives re-boots and
agrees on several computers can be computed from the

(+ epoch-of-zero-ticks
   (/ (tick-count) (ticks-per-second)))

Iff an uncounted leap second has intervened
between the epoch-of-zero-ticks and the
time the tick-count was taken then this
number will differ by more than one
from the (time-of-day).

That is appropriate, because the time of
day can not be used to compute exact
time intervals without knowledge of the
leap seconds.

  -- Keith

PS: maybe the tick-count should be made
a real number of seconds and renamed,
getting rid of ticks-per-second.


An account of bugs from messing up leap seconds:

Scheme-reports mailing list