Re: Clock precision and accuracy Lassi Kortela 11 May 2019 12:34 UTC

> The precision (nanosecond, millisecond, etc) should not be part of the time API.  Doing so leads to the kind of issues you mention and endless discussion of what is the most appropriate precision.  Time should be an abstract object that hides the precision (which can depend on the specifics of the lowlevel interface).
>
> Gambit has the time->seconds and seconds->time procedures to convert between time objects and a flonum giving the elapsed time since a reference point (unix epoch).  Internally Gambit uses flonums for time calculations such as I/O timeouts, thread scheduling quantums, etc

This is actually a very nice abstraction. It means implementations have
a lot of leeway to choose the easiest/fastest representation (or
representations) and users can have a portable and extensible API.

E.g. beside time->seconds you could add time->milliseconds,
time->microseconds and time->nanoseconds without disturbing the old API
at all. And the reverse: nanoseconds->time, etc.

Ditto with decomposed versions: time->seconds-and-nanoseconds, etc.

And different epochs: time->windows-filetime ("100-nanosecond intervals
since January 1, 1601 UTC", an interesting choice).

And none of these functions promise or demand a particular sub-second
precision for the internal representation, but as you say and as we seem
to happily agree, that's the point. Time precision is somewhat of a
cargo-cult thing: APIs like to say what the precision is but rarely do
they go back to the source of the timestamp to ascertain that the source
is capable of measuring time so precisely.

If multiple internal representations are permitted, lossless
round-tripping of timestamps also becomes possible. E.g. Unix stat()
returns seconds and nanoseconds as separate integers. If a (secs .
nsecs) representation can be used then e.g. the following will set "foo"
to have the exact same timestamp as "bar":

(set-file-time "foo" (get-file-time "bar"))

While it still remains possible to do things like (time->seconds
(get-file-time "bar")) etc.

The only problem is which of these procedures to include in the SRFI. We
could perhaps have time->os-filetime and os-filetime->time?

> As time passes, the (fixed) 52 significant bits of a 64 bit flonum will represent the seconds since the epoch with increased error.  Currently and for the next 20 years, the integer part of the time takes 31 bits and there are 21 bits left to represent the fraction of a second, which means the error is sub-microsecond for the next 20 years.  By that time architectures will probably have evolved to 128 bit flonums (alternatively a new epoch could be defined to reset the error).

Enlightening. I had never thought of it that way.

> Here are a few examples from Gambit:
>
>> (file-info ".")
> #<file-info #2
>     type: directory
>     device: 16777220
>     inode: 8606475805
>     mode: 493
>     number-of-links: 46
>     owner: 501
>     group: 20
>     size: 1472
>     last-access-time: #<time #3>
>     last-modification-time: #<time #4>
>     last-change-time: #<time #5>
>     attributes: 16
>     creation-time: #<time #6>>
>> (time->seconds (file-info-last-modification-time (file-info ".")))
> 1557425438.
>> (time->seconds (current-time))
> 1557573958.072262
>> (- (time->seconds (current-time)) (time->seconds (current-time)))
> -9.5367431640625e-7
>> (real-time)
> 166.17429184913635
>> (cpu-time)
> .035474