PanagiotisGeorgiadis / elm-datetime / Calendar

The Calendar module was introduced in order to keep track of the Calendar Date concept. It has no knowledge of Time therefore it can only represent a Date which consists of a Day, a Month and a Year. You can construct a Calendar Date either from a Posix time or by using its Raw constituent parts. You can use a Date and the Calendar's utilities as a standalone or you can combine a Date and a Time in order to get a DateTime which can then be converted into a Posix.

Type definition


type alias Date =
Internal.Date

A full (Gregorian) calendar date.


type alias RawDate =
{ year : Basics.Int
, month : Time.Month
, day : Basics.Int 
}

The raw representation of a calendar date.

Creating a Date

fromPosix : Time.Posix -> Date

Construct a Date from a Posix time. You can construct a Posix time from milliseconds using the millisToPosix function located in the elm/time package.

fromPosix (Time.millisToPosix 0)
-- Date { day = Day 1, month = Jan, year = Year 1970 } : Date

fromPosix (Time.millisToPosix 1566795954000)
-- Date { day = Day 26, month = Aug, year = Year 2019 } : Date

fromPosix (Time.millisToPosix 1566777600000)
-- Date { day = Day 26, month = Aug, year = Year 2019 } : Date

Notice that in the second and third examples the timestamps that are used are different but the resulting Dates are identical. This is because the Calendar module doesn't have any knowledge of Time which means that if we attempt to convert both of these dates back toMillis they will result in the same milliseconds. It is recommended using the fromPosix function provided in the DateTime module if you need to preserve both Date and Time.

fromRawParts : RawDate -> Maybe Date

Attempt to construct a Date from its (raw) constituent parts. Returns Nothing if any parts or their combination would form an invalid date.

fromRawParts { day = 25, month = Dec, year = 2019 }
-- Just (Date { day = Day 25, month = Dec, year = Year 2019 }) : Maybe Date

fromRawParts { day = 29, month = Feb, year = 2019 }
-- Nothing : Maybe Date

Conversions

toMillis : Date -> Basics.Int

Transforms a Date into milliseconds.

date = fromRawParts { day = 25, month = Dec, year = 2019 }
Maybe.map toMillis date -- Just 1577232000000 == 25 Dec 2019 00:00:00.000

want = 1566795954000 -- 26 Aug 2019 05:05:54.000
got = toMillis (fromPosix (Time.millisToPosix want)) -- 1566777600000 == 26 Aug 2019 00:00:00.000

want == got -- False

Notice that transforming a date to milliseconds will always get you midnight hours. The first example above will return a timestamp that equals to Wed 25th of December 2019 00:00:00.000 and the second example will return a timestamp that equals to 26th of August 2019 00:00:00.000 even though the timestamp we provided in the fromPosix was equal to 26th of August 2019 05:05:54.000

monthToInt : Time.Month -> Basics.Int

Convert a given Month to an integer starting from 1.

monthToInt Jan -- 1 : Int

monthToInt Aug -- 8 : Int

Accessors

getYear : Date -> Basics.Int

Extract the Year part of a Date.

-- date == 25 Dec 2019
getYear date -- 2019 : Int

getMonth : Date -> Time.Month

Extract the Month part of a Date.

-- date == 25 Dec 2019
getMonth date -- Dec : Month

getDay : Date -> Basics.Int

Extract the Day part of a Date.

-- date == 25 Dec 2019
getDay date -- 25 : Int

Setters

setYear : Basics.Int -> Date -> Maybe Date

Attempts to set the Year part of a Date.

-- date == 29 Feb 2020
setYear 2024 date -- Just (29 Feb 2024) : Maybe Date

setYear 2019 date -- Nothing : Maybe Date

setMonth : Time.Month -> Date -> Maybe Date

Attempts to set the Month part of a Date.

-- date == 31 Jan 2019
setMonth Aug date -- Just (31 Aug 2019) : Maybe Date

setMonth Apr date -- Nothing : Maybe Date

setDay : Basics.Int -> Date -> Maybe Date

Attempts to set the Day part of a Date.

-- date == 31 Jan 2019
setDay 25 date -- Just (25 Jan 2019) : Maybe Date

setDay 32 date -- Nothing : Maybe Date

Increment values

incrementYear : Date -> Date

Increments the Year in a given Date while preserving the Month and Day parts.

-- date  == 31 Jan 2019
incrementYear date -- 31 Jan 2020 : Date

-- date2 == 29 Feb 2020
incrementYear date2 -- 28 Feb 2021 : Date

Note: In the first example, incrementing the Year causes no changes in the Month and Day parts. On the second example we see that the Day part is different than the input. This is because the resulting date would be an invalid date ( 29th of February 2021 ). As a result of this scenario we fall back to the last valid day of the given Month and Year combination.

incrementMonth : Date -> Date

Increments the Month in a given Date. It will also roll over to the next year where applicable.

-- date  == 15 Sep 2019
incrementMonth date -- 15 Oct 2019 : Date

-- date2 == 15 Dec 2019
incrementMonth date2 -- 15 Jan 2020 : Date

-- date3 == 31 Jan 2019
incrementMonth date3 -- 28 Feb 2019 : Date

Note: In the first example, incrementing the Month causes no changes in the Year and Day parts while on the second example it rolls forward the 'Year'. On the last example we see that the Day part is different than the input. This is because the resulting date would be an invalid one ( 31st of February 2019 ). As a result of this scenario we fall back to the last valid day of the given Month and Year combination.

incrementDay : Date -> Date

Increments the Day in a given Date. Will also increment Month and Year where applicable.

-- date  == 25 Aug 2019
incrementDay date -- 26 Aug 2019 : Date

-- date2 == 31 Dec 2019
incrementDay date2 -- 1 Jan 2020 : Date

Decrement values

decrementYear : Date -> Date

Decrements the Year in a given Date while preserving the Month and Day parts.

-- date  == 31 Jan 2019
decrementYear date -- 31 Jan 2018 : Date

-- date2 == 29 Feb 2020
decrementYear date2 -- 28 Feb 2019 : Date

Note: In the first example, decrementing the Year causes no changes in the Month and Day parts. On the second example we see that the Day part is different than the input. This is because the resulting date would be an invalid date ( 29th of February 2019 ). As a result of this scenario we fall back to the last valid day of the given Month and Year combination.

decrementMonth : Date -> Date

Decrements the Month in a given Date. It will also roll backwards to the previous year where applicable.

-- date  == 15 Sep 2019
decrementMonth date -- 15 Aug 2019 : Date

-- date2 == 15 Jan 2020
decrementMonth date2 -- 15 Dec 2019 : Date

-- date3 == 31 Dec 2019
decrementMonth date3 -- 30 Nov 2019 : Date

Note: In the first example, decrementing the Month causes no changes in the Year and Day parts while on the second example it rolls backwards the Year. On the last example we see that the Day part is different than the input. This is because the resulting date would be an invalid one ( 31st of November 2019 ). As a result of this scenario we fall back to the last valid day of the given Month and Year combination.

decrementDay : Date -> Date

Decrements the Day in a given Date. Will also decrement Month and Year where applicable.

-- date  == 27 Aug 2019
decrementDay date -- 26 Aug 2019 : Date

-- date2 == 1 Jan 2020
decrementDay date2 -- 31 Dec 2019 : Date

Compare values

compare : Date -> Date -> Basics.Order

Compares the two given Dates and returns an Order.

-- past   == 25 Aug 2019
-- future == 26 Aug 2019
compare past past -- EQ : Order

compare past future -- LT : Order

compare future past -- GT : Order

Utilities

getDateRange : Date -> Date -> List Date

Returns an incrementally sorted Date list based on the start and end date parameters. The resulting list will include both start and end dates.

-- start == 26 Feb 2020
-- end   == 1 Mar 2020

getDateRange start end
-- [ 26 Feb 2020, 27 Feb 2020, 28 Feb 2020, 29 Feb 2020, 1  Mar 2020 ] : List Date

getDateRange end start
-- [ 26 Feb 2020, 27 Feb 2020, 28 Feb 2020, 29 Feb 2020, 1  Mar 2020 ] : List Date

getDatesInMonth : Date -> List Date

Returns a list of Dates for the given Year and Month combination.

-- date == 26 Aug 2019

getDatesInMonth date
-- [ 1 Aug 2019, 2 Aug 2019, 3 Aug 2019, ..., 29 Aug 2019, 30 Aug 2019, 31 Aug 2019 ] : List Date

getDayDiff : Date -> Date -> Basics.Int

Returns the difference in days between two Dates. We can have a negative difference of days as can be seen in the examples below.

-- past   == 24 Aug 2019
-- future == 26 Aug 2019
getDayDiff past future -- 2  : Int

getDayDiff future past -- -2 : Int

getFollowingMonths : Time.Month -> List Time.Month

Returns a list with all the following months in a Calendar Year based on the Month argument provided. The resulting list will not include the given Month.

getFollowingMonths Aug -- [ Sep, Oct, Nov, Dec ] : List Month

getFollowingMonths Dec -- [] : List Month

getPrecedingMonths : Time.Month -> List Time.Month

Returns a list with all the preceding months in a Calendar Year based on the Month argument provided. The resulting list will not include the given Month.

getPrecedingMonths May -- [ Jan, Feb, Mar, Apr ] : List Month

getPrecedingMonths Jan -- [] : List Month

getWeekday : Date -> Time.Weekday

Returns the weekday of a specific Date.

-- date == 26 Aug 2019
getWeekday date -- Mon : Weekday

isLeapYear : Date -> Basics.Bool

Checks if the Year part of the given Date is a leap year.

-- date  == 25 Dec 2019
isLeapYear date -- False

-- date2 == 25 Dec 2020
isLeapYear date2 -- True

lastDayOf : Date -> Basics.Int

Returns the last day of the combination of the Year and Month parts of the given Date.

-- date == 1 Dec 2018
lastDayOf date -- 31 : Int

-- date2 == 1 Feb 2019
lastDayOf date2 -- 28 : Int

-- date3 = 1 Feb 2020
lastDayOf date3 -- 29 : Int

sort : List Date -> List Date

Sorts incrementally a list of Dates.

-- past   == 26 Aug 1920
-- epoch  == 1 Jan 1970
-- future == 25 Dec 2020

sort [ future, past, epoch ]
-- [ 26 Aug 1920, 1 Jan 1970, 25 Dec 2020 ] : List Date

Constants

months : Array Time.Month

Returns a list of all the Months in Calendar order.

millisInADay : Basics.Int

Returns the milliseconds in a day.