module Data.Time.ISO8601 ( formatISO8601 , formatISO8601Millis , formatISO8601Micros , formatISO8601Nanos , formatISO8601Picos , formatISO8601Javascript , parseISO8601 ) where import Data.Time.Clock (UTCTime) import Data.Time.Format (formatTime, parseTime) import System.Locale (defaultTimeLocale) -- | Formats a time in ISO 8601, with up to 12 second decimals. -- -- This is the `formatTime` format @%FT%T%Q@ == @%%Y-%m-%dT%%H:%M:%S%Q@. -- -- For formatISO8601 :: UTCTime -> String formatISO8601 t = formatTime defaultTimeLocale "%FT%T%QZ" t -- | Pads an ISO 8601 date with trailing zeros, but lacking the trailing Z. formatPadded :: UTCTime -> String formatPadded t | length str == 19 = str ++ ".000000000" | otherwise = str ++ "000000000" where str = formatTime defaultTimeLocale "%FT%T%Q" t -- | Formats a time in ISO 8601 with up to millisecond precision and trailing zeros. -- The format is precisely: -- -- >YYYY-MM-DDTHH:mm:ss.sssZ formatISO8601Millis :: UTCTime -> String formatISO8601Millis t = take 23 (formatPadded t) ++ "Z" -- | Formats a time in ISO 8601 with up to microsecond precision and trailing zeros. -- The format is precisely: -- -- >YYYY-MM-DDTHH:mm:ss.ssssssZ formatISO8601Micros :: UTCTime -> String formatISO8601Micros t = take 26 (formatPadded t) ++ "Z" -- | Formats a time in ISO 8601 with up to nanosecond precision and trailing zeros. -- The format is precisely: -- -- >YYYY-MM-DDTHH:mm:ss.sssssssssZ formatISO8601Nanos :: UTCTime -> String formatISO8601Nanos t = take 29 (formatPadded t) ++ "Z" -- | Formats a time in ISO 8601 with up to picosecond precision and trailing zeros. -- The format is precisely: -- -- >YYYY-MM-DDTHH:mm:ss.ssssssssssssZ formatISO8601Picos :: UTCTime -> String formatISO8601Picos t = take 32 (formatPadded t) ++ "Z" -- | Formats a time like JavaScript's @new Date().toISOString()@ -- as specified by Mozilla: -- -- This is an alias for `formatISO8601Millis`. formatISO8601Javascript :: UTCTime -> String formatISO8601Javascript = formatISO8601Millis -- | Parses an ISO 8601 string. parseISO8601 :: String -> Maybe UTCTime parseISO8601 t = parseTime defaultTimeLocale "%FT%T%QZ" t