time since the epoch

Stefan Karrmann sk@mathematik.uni-ulm.de
Sun, 9 Feb 2003 10:57:25 +0100


Peter Thiemann (Thu, Feb 06, 2003 at 12:40:14PM -0800):
> John's code illustrates TimeDiff's deficiencies perfectly:
> 
> There is also a more fundamental problem with the TimeDiff data
> type. While seconds, minutes, hours, and days are clearly specified
> amounts of time, the duration of a month or a year may vary depending
> on the reference point where the time difference is applied.

What time takes a year - 365 or 366 days? There are leap years!
What time takes a month - 28, 29, 30 or 31 days?
A week takes 7 days.
How long is a day - 86399, 86400 or 86401 seconds and how long is a
hour - 3599, 3600 or 3601 seconds? There are leap seconds!
A second is the basic amount of time.

> My conclusion is that time differences really should be measured in
> seconds and picoseconds. 

How do you measure 100 attoseconds?

> type TimeDiff = (Integer, Integer)

More general is

newtype TimeDiff = TimeDiff Rational
   deriving (Eq, Ord)

> Hmm, this is underspecified!
> As another poster said, (pointing out http://cr.yp.to/libtai, but it
> is better to look at http://cr.yp.to/time.html, which has a discussion
> on UTC vs TAI vs UNIX time) the official source of time is TAI, so it
> is best to base a time library
> *on the number of TAI seconds since a reference date*
> (which is btw what the libtai is all about).
> For compatibility with UNIX time, "Arthur David Olson's popular time
> library uses an epoch of 1970-01-01 00:00:10 TAI"
> [http://cr.yp.to/proto/utctai.html]. 
> So this mostly means that you need to set your system clock correctly:-)

No, you have to check for leap seconds. There is one in every few years.

> Hence, a suitable specification for 
>     JM> toRawTime :: ClockTime -> (Integer,Integer) 
> could be number of seconds since reference point, given as a pair
> (full seconds, picoseconds). This function *may* involve a time zone
> calculation for those that do not run their system clock on TAI (or UTC).
>     JM> fromRawTime :: (Integer,Integer) -> ClockTime
> with
>   toRawTime . fromRawTime == id
> and
>   fromRawTime . toRawTime ~~ id
>   (the internal representation of ClockTime may have less precision,
>   so the difference would be less than system dependent constant,
>   which could also be supplied by the library)
> 
> Given these two raw ingredients, everything else can be computed
> from that. In addition, it would be nice to have parsing functions for
> various time and date formats (which is what I ended up writing
> myself for the ISO8601 format).

Cheers,
-- 
Stefan Karrmann