Dear Sigbjorn
(This is cc'd to the Haskell list.  This message will be long and boring
to anyone not interested in the nuts and bolts of Time.)

Thank you for fixing Time.lhs.  But now I've looked at it again
I think it is still inadequate.  That's not your fault, it's
because the standard is.  TimeDiff is currently declared (by
the standard) to be

data TimeDiff = TimeDiff {
   tdYear, tdMonth, tdDay, tdHour, tdMin, tdSec :: Int,
   tdPicosec      :: Integer
   } deriving (Eq, Ord, Read, Show)

A TimeDiff is generated by the diffClockTime function.  
There are two problems.
  (a) the same time interval can be represented by two
      different TimeDiffs. 
  (b) a TimeDiff does not represent any fixed length of time.
As a result the "diffClockTimes" function is highly unspecified.
If I take (1st Apr 'diffClockTimes' 1st Mar) `addToClockTime` 1st Jun,
is the result the 1st July (I think this is what GHC does) or the 2nd July
(which is what you get if a TimeDiff has a fixed number of days).  

The problem is that both behaviours are desirable.  Sometimes you want
to say "1 month from now"; sometimes "30 days from now".  I think there
is an obvious logical solution to this.  Make the two kinds of time difference
have different types.  Thus
   class TimeDiff a where
      addToClockTime :: a -> ClockTime -> ClockTime
      diffClockTimes :: ClockTime -> ClockTime -> a
Have types all instances of TimeDiff
   TimeDiff = TimeDiff Integer -- time in picoseconds
   TimeDiffDays = TimeDiffDays Int -- time in days
   TimeDiffMonths = TimeDiffMonths Int -- time in months
   (We don't actually need any more, since a second is always 10^12 picoseconds,
   a year is always -- in the Gregorian Calendar -- 12 months, and so on.  But
   we could easily add them.)

As for implementation - 
   instance TimeDiff TimeDiff
can be done right now fairly easily, using standard C facilities.
Of course it could break code, but as the GHC TimeDiff was totally broken
until yesterday without anyone noticing, I don't think there'll be too
much squealing.
   instance TimeDiff TimeDiffDays 
and 
   instance TimeDiff TimeDiffMonths
are a little trickier, because you do I'm afraid need to do calculations in 
the Gregorian calendar, and I can't find any OS functions which will do those
calculations for me.  But they aren't very difficult - if people really want 
I'll do them.  Fortunately I don't think you need to know about either daylight
saving time or leap seconds for those.

Reply via email to