Haskell には、以下のような時間用の型がある。この記事は、どれを使えばいいかの解説。
- time ライブラリの Data.Time.Clock の UTCTime
- old-time ライブラリの System.Time の ClockTime
- base ライブラリの System.Posix.Types の EpochTime
UTCTime
速度を気にしないなら、UTCTime を使う。getCurrentTime で現在の時間を取得できる。
パーサーやプリティプリンタは Data.Time.Format を参照のこと。TimeLocale は、old-locale ライブラリのを使う。old でない locale ライブラリがないのは、Haskell の恥の一つ。
Data.Time.Format は、信じられないぐらい遅い。たまにプリティプリントする用途にはいいが、Web サーバのログ生成などには使ってはいけない。僕の経験では、CPU を 60% ぐらい消費していた。速いライブラリに関しては、後ほど説明。
ClockTime
古いコードを相手にする以外は使用禁止。
Haskell 98 で定義されていたが、Haskell 2010 で削られた型。Haskell 98 での定義は抽象データ型だが、TOD という構成子が公開されている。
data ClockTime = TOD Integer Integer
左が1970年1月1日から数えた秒で、右がピコ秒。なので、以下の EPochTime には簡単に変換できる。
getClockTime で現在の時間を取得できる。
EpochTime
unix ライブラリを利用すると、必然的に使うようになる型。EpochTime は CTime の別名であり、これは C の time_t に対応する。なので、環境によって Int32 だったり、Int64 だったりする。
epochTime で現在の時間を取得できる。
変換
適当に書いた変換関数。間違いの指摘を歓迎。
from\to | UTCTime | ClockTime | EpochTime |
---|---|---|---|
UTCTime | id | uToC | uToE |
ClockTime | cToU | id | cToE |
EpochTime | eToU | eToC | id |
import Data.Time (UTCTime) import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds) import Foreign.C.Types (CTime(..)) import System.Posix.Types (EpochTime) import System.Time (ClockTime(..)) uToC :: UTCTime -> ClockTime uToC t = TOD (truncate . utcTimeToPOSIXSeconds $ t) 0 uToE :: UTCTime -> EpochTime uToE = CTime . truncate . utcTimeToPOSIXSeconds cToU :: ClockTime -> UTCTime cToU (TOD t _) = posixSecondsToUTCTime . realToFrac $ t cToE :: ClockTime -> EpochTime cToE (TOD t _) = fromInteger t eToU :: EpochTime -> UTCTime eToU = posixSecondsToUTCTime . realToFrac eToC :: EpochTime -> ClockTime eToC (CTime t) = TOD (fromIntegral t) 0