This post gives some basic examples for the usage of Haskell's Data.Time library. Import it with import Data.Time
in ghci to follow along.
For further information have a look at A Haskell Time Library Tutorial and time's documentation on Hackage.
How get the current date (today) and the current time (now)
> now <- getCurrentTime
now :: UTCTime
> now
2020-06-24 06:53:01.183008039 UTC
> today = utctDay now
today :: Day
> today
2020-06-24
How to create a specific Day
There are two methods, fromGregorian
and fromGregorianValid
. The former returns a valid day close to what you asked it to do, the latter returns either Just day
, or Nothing
. The difference becomes obvious when you ask it to create e.g. February 31st:
-- some invalid examples
> fromGregorian 2020 2 31
2020-02-29
it :: Day
> fromGregorianValid 2020 2 31
Nothing
it :: Maybe Day
-- some valid examples
> fromGregorian 2016 9 27
2016-09-27
it :: Day
> fromGregorianValid 2019 10 7
Just 2019-10-07
it :: Maybe Day
How to format date and time
> now <- getCurrentTime
> formatTime defaultTimeLocale "%d.%m.%Y, %H:%M" now
"24.06.2020, 13:48"
it :: String
Check which day it is
> now <- getCurrentTime
> today = utctDay now
> dayOfWeek today
Wednesday
it :: DayOfWeek
Date and Time calculations
You can add (or substract) seconds to a time
> now <- getCurrentTime
> workFinished = addUTCTime (60*60*8) now -- add 8 hours
and add days to a date
> today = utctDay now
> tomorrow = addDays 1 today
> yesterday = addDays (-1) today
You can handle durations expressed in months as well:
> jan6 = fromGregorian 2020 1 6
> addGregorianMonthsRollOver 1 jan6
2020-02-06
it :: day
> addGregorianMonthsClip 1 jan6
2020-02-06
it :: day
When do you need addGregorianMonthsRollOver
and when addGregorianMonthsClip
? Depends on your business case! Imagine a customer buys something for "a month", what does that mean exactly for you? It could mean "30 days", then use addDays
. It could mean "increment month (and year if necessary) by one", but what happens on January 31st? There's no Februar 31st, so should the result be Februar 28th (or 29th in a leap year) (addGregorianMonthsClip
) or March 3rd (or 2nd in a leap year) -- use addGregorianMonthsRollOver
in that case.
> jan31 = fromGregorian 2020 1 31
> addGregorianMonthsRollOver 1 jan31
2020-03-02
> addGregorianMonthsClip 1 jan31
2020-02-29