
"SM" == Simon Marlow
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]" ?