以下で紹介している関数は全て、Haskellのtimeパッケージをインストールして、
import Data.Time
-- 一部はこれも
import Data.Time.Clock.POSIX
とすれば使えます。
日時を扱う
現在のタイムスタンプを取得する関数はgetCurrentTime
です。戻り値はUTCTime
型です。
getCurrentTime
--> 2019-09-16 06:59:38.751786 UTC
文字列 –> UTCTime
文字列からUTCTime
データを作成するには2つ方法があり、一つはread
を使って
read "2019-09-16 14:00:00.012345" :: UTCTime
--> 2019-09-16 14:00:00.012345 UTC
これはそのままUTCTime
型で取得できるので便利ですが、元の文字列が正しい形式でなかった場合に例外を出すので危険です。
もう一つは、文字列をパースする方法で、parseTimeM
という関数がData.Time.Formatにあります。型は
parseTimeM
:: (Monad m, ParseTime t) =>
Bool -> TimeLocale -> String -> String -> m t
少し複雑なので使い方から入りましょう。
parseTimeM True defaultTimeLocale "%Y-%m-%d %H:%M:%S.%q" "2019-10-30 09:12:59.000000000001" :: Maybe UTCTime
--> Just 2019-10-30 09:12:59.000000000001 UTC
ドキュメントによれば第一引数は、文字列の先頭・末尾に空白がある場合に自動でトリムするかどうかを指定します。False
にした場合は、先頭・末尾に空白があった場合にフォーマット違反とみなされNothing
が返ってきます。
(実際に試してみると、False
にしていても先頭の空白は自動でトリムされてJust
で返ってきました。)
第二引数はタイムゾーン、第三引数にフォーマット、第四引数にパースしたい文字列を指定します。
ちなみに%q
はピコ秒のことで、12桁の数字列を要求します。ミリ秒とマイクロ秒は無さそうでした。
POSIXTime –> UTCTime
POSIXTimeからHaskellのUTCTime型に変換するにはData.Time.Clock.POSIXにあるposixSecondsToUTCTime
という関数が使えます。
import Data.Time.Clock.POSIX
posixSecondsToUTCTime 0
--> 1970-01-01 00:00:00 UTC
posixSecondsToUTCTime 1570775400
--> 2019-10-11 06:30:00 UTC
UTCTime –> POSIXTime
同モジュール内には、これとは逆にUTCTimeからPOSIXTimeに変換するutcTimeToPOSIXSeconds
という関数もあります。
-- UTCTime
utcNow <- getCurrentTime
utcNow
--> 2020-01-22 23:39:23.039432 UTC
utcTimeToPOSIXSeconds utcNow
--> 1579736363.039432s
任意のDayデータを作成する方法
Haskellで日時ではなく日付までを扱いたい場合、Data.Time.Calendarというモジュール内にDay
という型があり、これを使います。
fromGregorian 2019 9 16
--> 2019-09-16
整数型で年、月、日を引数で渡すと、Day
型データを返してくれます。文字列からの場合は、UTCTime
の時と同様、parseTimeM
が使えるようです。
現在の日付を取得する
こちらは、まず現在のタイムスタンプを取得して(UTCTime
型)、そこからutctDay
という関数を使ってDay
を取得します。utctDay
はData.Time.Clockで提供されています。
now <- getCurrentTime
utctDay now
--> 2019-09-16
年、月、日、をそれぞれ整数値として別個に取得したい場合は、toGregorian
が使えます。最初に紹介した関数の逆関数ですね。以下に書いた例のように、年月日をタプルで返してきます。
today <- return . utctDay =<< getCurrentTime
toGregorian today
--> (2019, 09, 16)