Time Library Date Normalisation and Arithmetic
Ashley Yakeley
ashley at semantic.org
Sat Jul 9 07:36:41 EDT 2005
I'm thinking of something along these lines:
Normalisation
-------------
class (Eq a,Ord a) => Normalisable a where
isNormal :: a -> Bool
normaliseTruncate :: a -> a
normaliseRollover :: a -> a
The normalise functions would work like this:
normaliseTruncate
2005/14/32 -> 2005/12/32 -> 2005/12/31
2005/-2/-4 -> 2005/01/-4 -> 2005/01/01
normaliseRollover
2005/14/32 -> 2006/02/32 -> 2006/03/04
2005/-2/-4 -> 2004/10/-4 -> 2004/09/26
(doing both steps in each call)
Calendar Arithmetic
-------------------
This is one way of providing arithmetic for such things as Gregorian
dates:
data TimeUnit d = TimeUnit
addTimeUnitTruncate :: Integer -> d -> d
addTimeUnitRollover :: Integer -> d -> d
diffTimeUnitFloor :: d -> d -> Integer
days :: (DayEncoding d) => TimeUnit d
gregorianMonths :: (DayEncoding d) => TimeUnit d
gregorianYears :: (DayEncoding d) => TimeUnit d
So for instance, to add three months to a date d, you do this:
d' = addTimeUnitTruncate gregorianMonths 3 d
This might also be used for minutes and so forth. And you might also be
able to do this:
multipleTimeUnit :: Integer -> TimeUnit d -> TimeUnit d
weeks = multipleTimeUnit 7 days
There's an alternative way using classes, for days only:
class (Integral u) => TimeUnit u where
addTimeUnitTruncate :: (DayEncoding d) => u -> d -> d
addTimeUnitRollover :: (DayEncoding d) => u -> d -> d
diffTimeUnitFloor :: (DayEncoding d) => d -> d -> u
newtype Days = Days Integer
instance TimeUnit Days
newtype GregorianMonths = GregorianMonths Integer
instance TimeUnit GregorianMonths
newtype GregorianYears = GregorianYears Integer
instance TimeUnit GregorianYears
d' = addTimeUnitTruncate (GregorianMonths 3) d
My preference is for the former.
--
Ashley Yakeley, Seattle WA
More information about the Libraries
mailing list