Time library design proposal

S. Alexander Jacobson haskell at alexjacobson.com
Tue Feb 1 18:30:53 EST 2005


I read the discussion of Time Library 
organization, but did not feel like it arrived 
anywhere.  The current design seems like it was 
expedient for its time, but does not feel 
particularly robust.  It does not handle typical 
usecases well and provides little protection from 
user error.  So I'm going to take a shot at a 
proposal:
----

The Y2K problem
---------------
It would be nice if the library was explicit about 
whether year was 2 or 4 digits.  Why not define 
year like this:

   newtype Year = Year Int -- don't export constructor
   mkYear century centyear = Year (100*century+centyear)
   mkBigYear millenium cent centyear = ...

Allow Dates without Times
-------------------
There are lots of contexts in which you want a 
date and not a time e.g. storing birthdates.  Is 
there any reason the Time library shouldn't have a 
standard Date type e.g.

   data Date = {month::Month,day::Day,year::Year}


Don't allow imposible weekdays
------------------------------
Weekday and yearday seem like they should be 
functions on this Date type and not part of the 
datastructure (you shouldn't be able to produce 
weekdays that don't match dates).

   weekDay::Date->WeekDay

Don't allow impossible times
----------------------------
The type of hour minute and second should protect 
the user from 28 o'clock and making appointments 
for 31:101 PM So we probably want:

   data Hour =  H0 | H1 | H2 ... H23
   data Minute = M0 | M1 | M2 ... M59
   data Second = S0 | S1 | S2 ... S59
   data AMPM = AM | PM

Times Types
-----------
There are also lots of contexts where you want a 
time but not a date e.g. an alarm clock....

   data Time =
           {hour::Hour
           ,minute::Minute
           ,second::Second
           ,millis::Int
           ,isDST::Bool,
           ,timeZone::TimeZone
 	}

If you have a leap second time that doesn't work 
in this model, round it!  The 99.9999% case does 
not need to be sacrificed for the occasional 
physicist who need to know that the time is is 
24:00:03.

Re millis, yes it seems like it should be 
Rational, but this is human meaninful time.  And 
humans don't care about millis.  We can then 
produce a DateTime as

   data DateTime = DateTime {date::Date,time::Time}

Epochal High Precision Time
--------------------------
If you are doing physicist calculations, then use:

   data EpochTime a =
     EpochTime {seconds::Integer
               ,fraction::Ratio a
               ,precision::Integer
               }

precision specifies the maximum size of the 
denominator of the fraction.

   epochTimeToDateTime::Epoch->DateTime

The existing TimeDiff is totally bizarre.  If 
tdSec == 3600 is that an error or is that the same 
as tdSec == 0 and tdHour == 1?  How many months 
are a difference in months?  It all seems too 
application specific to belong in a library.  I 
don't have a particular good idea here.  I think 
EpochTime does what you need in a library.

The last major element we need is:

    getEpochTime::IO EpochTime

Analogous to the old getClockTime but includes the 
resolution of the system clock.

-Alex-

______________________________________________________________
S. Alexander Jacobson tel:917-770-6565 http://alexjacobson.com


More information about the Libraries mailing list