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