Date operations

Date operations

Extracting elements out of a Date

Extracting a Year, Month or a Day out of a Date is simple.

We can deconstruct via pattern matching:

let (Date myYear myMonth myDay) = myDate

Or we can use the year, month, day and weekday functions:

let myYear = year myDate
    myMonth = month myMonth
    myDay = day myMonth
    myWeekday = weekday myMonth

Adjusting a Date

adjust adjusts a Date using a Duration in Days.

adjust :: Days -> Date -> Maybe Date

The result is a Maybe because the number of days must already be an integer and fall within the valid range of values for the Int type, and the resulting date must be in the valid dates range.

When converting durations (using convertDuration) to Days there’s no guarantee that the end result will be an integer. A possible solution could be using floor:

  -- let's say we have a duration in minutes.
  let (Days ds) = convertDuration minsDuration 
      newDate = adjust (Days $ floor ds) oldDate

Difference between two Dates

To calculate the difference between two Dates we can use diff.

diff :: forall d. Duration d => Date -> Date -> d

The result of diff is one of the types (Days, Hours, Minute, Seconds, Milliseconds) which implements the Duration type class. We need to help the compiler by specifying the type when it’s not clear from the context.


daysDiff :: Days
daysDiff = diff date1 date2

hoursDiff :: Hours
hoursDiff = diff date1 date2

Finding the last Day of a Month

Given a Year and a Month we can get the last Day of the Month by using lastDayOfMonth.

lastDayOfMonth :: Year -> Month -> Day

Checking wheter a Year is a leap year

isLeapYear checks whether a Year is a leap year according to the proleptic Gregorian calendar.

isLeapYear :: Year -> Boolean

Additional operations

  • Finding first/last weekday of a month
  • Finding last weekday before date
  • Finding first weekday after date