Haskell and Time
- Magnus Therning
I’ve found myself getting confused over the Data.Time modules a few times now. Today I wanted to do something that I ought to be simple both to do (it was) and find out how to do (it wasn’t, at least not for me). I thought I’d write it down, because I’m bound to forget about it otherwise, and it might be helpful for some other poor soul out there.
I wanted to store a date in a database (SQLite) using Haskell (HDBC). Since I’m only interested in the date and not the time I chose to represent it in Haskell as a Date.Time.Calendar.Day. For Day
0 means 1858-11-17. HDBC on the other hand needs the date in seconds since epoch (1970-01-01 00:00 UTC), which conveniently can be represented with a single Integer
. Time.Data.Clock.POSIX contains a few handy functions to convert between POSIXTime
(NominalDiffTime
) and UTCTime
. However, there are no special functions for converting between an Integer
and NominalDiffTime
. The way I found was to do it via the class types that NominalDiffTime
implements.
First I thought that Enum
might offer the solution, but my experiments with that was a bit confusing:
> pt <- getPOSIXTime
1221603766.526661s
> fromEnum pt
4118657661830593344
> toEnum 4118657661830593344 :: POSIXTime
4118657.661830593344s
Not really the result I had hoped for. No, instead the function to use to get the Integer
is floor
, and the only way I found to convert a NominalDiffTime
from an Integer
is to go via a Ratio
:
> fromRational (1221603766 % 1) :: POSIXTime
1221603766s
Have I missed something or is this the best way to achieve this?