time since the epoch

Peter Thiemann thiemann@informatik.uni-freiburg.de
07 Feb 2003 10:22:12 -0800

>>>>> "SM" == Simon Marlow <simonmar@microsoft.com> writes:

    >> Ha! After playing with this, I discovered that only the seconds were
    >> set and all other fields remained untouched. At least in ghc's
    >> implementation. Interestingly, TimeDiff derives Eq and Ord, but I'd
    >> better not ask for their implementation...

    SM> TimeDiff has a perfectly well-defined meaning for Eq and Ord: one
    SM> TimeDiff is equal to another iff all the fields are respectively equal.

Yes, sure, Eq and Ord are defined by 
  deriving (Eq, Ord, ...)
but this does not make much sense if the representation for a
particular duration is not unique. All I'm asking for is a unique
representation for a duration and I do not see how you can do this
using not uniquely defined terms like "month" and "year".
As an aside, you can easily define convenience functions that map your
(application's) idea of months and years to seconds, but it would be
much harder the other way round.

    >> 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.

    SM> This isn't a problem with the spec, I think.  A TimeDiff of "1 month" is
    SM> precisely a difference, which, when added to a given ClockTime, produces
    SM> a ClockTime which is one month later (with respect to some timezone,
    SM> presumably UTC since it isn't specified otherwise).  That is, January
    SM> 12th 12:00 UTC becomes February 12th 12:00 UTC, and so on.  Adding one
    SM> month to certain ClockTimes is meaningless: eg. adding one month to
    SM> January 31st doesn't work.

Unfortunately, with UTC, this goes on to make adding *anything* except
seconds to certain ClockTimes (namely the instants of leap seconds,
eg, what happens if you add 1 minute to 23:59:60 ? This is a perfectly
legal UTC time on a day with a leap second) meaningless. My take would
be to look at an established standard for expressing time durations
(eg, ISO8601) and just adhere to that (but not the POSIX standard,
please!). Personally, I think that it is unacceptable to make
something like addToClockTime a partial function.

    SM> At least, that's how I believe it is supposed to work.  GHC's
    SM> implementation *is* completely wrong (which is perhaps where some of the
    SM> confusion comes from), but the TimeExts library can be used instead of
    SM> TimeDiffs.

Well, so you agree that the behavior of the Time module is
unspecified! Of course, I'm not blaming GHC's implementation which
cannot be right under these circumstances.

    >> My conclusion is that time differences really should be measured in
    >> seconds and picoseconds. 
    >> type TimeDiff = (Integer, Integer)

    SM> We already have this kind of TimeDiff: just don't use anything except
    SM> the seconds and picoseconds fields.

Indeed, I found by experimentation that diffClockTimes only fills in
these two fields so that my attempt to compare the result with 
TimeDiff{ 0... tdDay = 14 ... 0 }
was doomed.

Unfortunately, the tdSec field has type Int, so its range is too small
to be useful.

    SM> I agree with John Meacham in that it ought to be possible to get a raw
    SM> time in terms of seconds/picoseconds since the epoch, and indeed GHC
    SM> lets you do that: importing System.Time lets you get at the
    SM> representation of ClockTime:

    SM> data ClockTime
    SM>   = TOD Integer 	-- Seconds since 00:00:00 on 1 Jan 1970
    SM>         Integer		-- Picoseconds with the specified second

    SM> This is a perfectly reasonable definition of absolute time, we don't
    SM> need to talk about TAI at all, except to define what the epoch means.

Agreed! So what is epoch? Is it
"Seconds since 00:00:00 on 1 Jan 1970 [TAI]"