In the IHP web framework, columns with the Postgres “Date” type
are translated into Haskell as the Day type.
Looking at the docs for Day
, it isn’t exactly clear how to create a Day
value from a time string. Here’s how to do this for a simple case:
parseDay :: String -> Day
parseDay = parseTimeOrError True defaultTimeLocale "%Y-%m-%d"
which will produce a Day
value given a string of the form 2020-12-29
. NOTE: if the string is not valid, an error will be thrown.
For better error handling, use parseTimeM
, which is executed in the context of any MonadFail
, such as the Maybe
monad:
parseDay' :: String -> Maybe Day
parseDay' = parseTimeM True defaultTimeLocale "%Y-%m-%d"
For info on all the different format options for the format string, see here.
Example
In my application, dates from the feed I was parsing had the form 2020-12-28T16:32:12+00:00
.
I did not need the time info, so I could call parseDay
as such:
parseDay $ takeWhile ('T' /=) (cs date)
which uses the cs
function from Data.String.Conversions
, included with IHP, to convert seamlessly between string types.
With the Day
object, we can then create an IHP record. Here’s an example from my data loading script:
itemNodeToEpisode :: ItemNode -> Episode
itemNodeToEpisode ItemNode {..} =
newRecord @Episode
|> set #title title
|> set #description description
|> set #link link
|> set #audioLink audioLink
|> set #date (parseDay $ takeWhile ('T' /=) (cs date))