Epoch in Haskell
A common requirement in programs is getting the number of seconds, milliseconds, or nanoseconds since the Unix epoch. Here’s how to do it in Haskell.
import Data.Time.Clock.POSIX (getPOSIXTime, POSIXTime)
import Data.Time.Clock (UTCTime, getCurrentTime)
import Data.Time.Format (formatTime, defaultTimeLocale)
main :: IO ()
main = do
now <- getCurrentTime
putStrLn $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q %z" now
posixTime <- getPOSIXTime
let seconds = floor posixTime :: Integer
let milliseconds = floor (posixTime * 1000) :: Integer
let nanoseconds = floor (posixTime * 1000000000) :: Integer
print seconds
print milliseconds
print nanoseconds
let utcFromSeconds = posixSecondsToUTCTime $ fromIntegral seconds
let utcFromNanoseconds = posixSecondsToUTCTime $ fromIntegral nanoseconds / 1000000000
putStrLn $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S %z" utcFromSeconds
putStrLn $ formatTime defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q %z" utcFromNanoseconds
posixSecondsToUTCTime :: POSIXTime -> UTCTime
posixSecondsToUTCTime = id
In Haskell, we use the Data.Time
library to work with time-related functions. The getPOSIXTime
function returns the current time as the number of seconds since the Unix epoch.
We use getCurrentTime
to get the current time, and formatTime
to format it as a string.
To get the elapsed time since the Unix epoch in seconds, milliseconds, or nanoseconds, we multiply the POSIX time by the appropriate factor and convert it to an integer.
You can also convert integer seconds or nanoseconds since the epoch into the corresponding UTCTime
. In this example, we use posixSecondsToUTCTime
to perform this conversion.
Here’s an example of what the output might look like:
$ runhaskell epoch.hs
2023-05-15 10:30:45.123456 +0000
1684146645
1684146645123
1684146645123456000
2023-05-15 10:30:45 +0000
2023-05-15 10:30:45.123456 +0000
Next, we’ll look at another time-related task: time parsing and formatting.