From b42f489e341cc038d431412bf7d4381049044902 Mon Sep 17 00:00:00 2001 From: amesgen Date: Sat, 11 Sep 2021 12:59:47 +0200 Subject: [PATCH] Add `FromDhall`/`ToDhall` for `LocalTime`/`ZonedTime`/`UTCTime` --- dhall/src/Dhall/Marshal/Decode.hs | 45 +++++++++++++++++++++++++++++++ dhall/src/Dhall/Marshal/Encode.hs | 20 ++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/dhall/src/Dhall/Marshal/Decode.hs b/dhall/src/Dhall/Marshal/Decode.hs index 5b533585b6..745298f197 100644 --- a/dhall/src/Dhall/Marshal/Decode.hs +++ b/dhall/src/Dhall/Marshal/Decode.hs @@ -60,6 +60,9 @@ module Dhall.Marshal.Decode , timeOfDay , day , timeZone + , localTime + , zonedTime + , utcTime -- ** Containers , maybe , pair @@ -326,6 +329,15 @@ instance FromDhall Time.Day where instance FromDhall Time.TimeZone where autoWith _ = timeZone +instance FromDhall Time.LocalTime where + autoWith _ = localTime + +instance FromDhall Time.ZonedTime where + autoWith _ = zonedTime + +instance FromDhall Time.UTCTime where + autoWith _ = utcTime + {-| Note that this instance will throw errors in the presence of duplicates in the list. To ignore duplicates, use `setIgnoringDuplicates`. -} @@ -950,6 +962,39 @@ timeZone = Decoder {..} expected = pure TimeZone +{-| Decode `Time.LocalTime` + +>>> input localTime "2020-01-01T12:34:56" +2020-01-01 12:34:56 +-} +localTime :: Decoder Time.LocalTime +localTime = record $ + Time.LocalTime + <$> field "date" day + <*> field "time" timeOfDay + +{-| Decode `Time.ZonedTime` + +>>> input zonedTime "2020-01-01T12:34:56+02:00" +2020-01-01 12:34:56 +02:00 +-} +zonedTime :: Decoder Time.ZonedTime +zonedTime = record $ + adapt + <$> field "date" day + <*> field "time" timeOfDay + <*> field "timeZone" timeZone + where + adapt date time = Time.ZonedTime (Time.LocalTime date time) + +{-| Decode `Time.UTCTime` + +>>> input utcTime "2020-01-01T12:34:56+02:00" +2020-01-01 10:34:56 UTC +-} +utcTime :: Decoder Time.UTCTime +utcTime = Time.zonedTimeToUTC <$> zonedTime + {-| Decode a `Maybe`. >>> input (maybe natural) "Some 1" diff --git a/dhall/src/Dhall/Marshal/Encode.hs b/dhall/src/Dhall/Marshal/Encode.hs index 545ae6f822..5223ef7639 100644 --- a/dhall/src/Dhall/Marshal/Encode.hs +++ b/dhall/src/Dhall/Marshal/Encode.hs @@ -333,6 +333,26 @@ instance ToDhall Time.TimeZone where declared = TimeZone +instance ToDhall Time.LocalTime where + injectWith _ = recordEncoder $ + adapt + >$< encodeField "date" + >*< encodeField "time" + where + adapt (Time.LocalTime date time) = (date, time) + +instance ToDhall Time.ZonedTime where + injectWith _ = recordEncoder $ + adapt + >$< encodeField "date" + >*< encodeField "time" + >*< encodeField "timeZone" + where + adapt (Time.ZonedTime (Time.LocalTime date time) timeZone) = (date, (time, timeZone)) + +instance ToDhall Time.UTCTime where + injectWith = contramap (Time.utcToZonedTime Time.utc) . injectWith + {-| Note that the output list will be sorted. >>> let x = Data.Set.fromList ["mom", "hi" :: Text]