Elixir 1.3 added a calendar module and four new date- and time-related types. Initially, they were little more than data holders, but Elixir 1.5 started to add some functionality to them.
The Calendar module represents the rules used to manipulate dates. The only current implementation is Calendar.ISO, the ISO-8601 representation of the Gregorian calendar.[5]
The Date type holds a year, a month, a day, and a reference to the ruling calendar.
| iex> d1 = Date.new(2018, 12, 25) |
| {:ok, ~D[2018-12-25]} |
| iex> {:ok, d1} = Date.new(2018, 12, 25) |
| {:ok, ~D[2018-12-25]} |
| iex> d2 = ~D[2018-12-25] |
| ~D[2018-12-25] |
| iex> d1 == d2 |
| true |
| iex> Date.day_of_week(d1) |
| 2 |
| iex> Date.add(d1, 7) |
| ~D[2019-01-01] |
| iex> inspect d1, structs: false |
| "%{__struct__: Date, calendar: Calendar.ISO, day: 25, month: 12, year: 2018}" |
(The sequences ~D[...] and ~T[...] are examples of Elixir’s sigils. They are a way of constructing literal values. We’ll see them again when we look at strings and binaries.)
Elixir can also represent a range of dates:
| iex> d1 = ~D[2018-01-01] |
| ~D[2018-01-01] |
| iex> d2 = ~D[2018-06-30] |
| ~D[2018-06-30] |
| iex> first_half = Date.range(d1, d2) |
| #DateRange<~D[2018-01-01], ~D[2018-06-30]> |
| iex> Enum.count(first_half) |
| 181 |
| iex> ~D[2018-03-15] in first_half |
| true |
The Time type contains an hour, a minute, a second, and fractions of a second. The fraction is stored as a tuple containing microseconds and the number of significant digits. (The fact that time values track the number of significant digits in the seconds field means that ~T[12:34:56.0] is not equal to ~T[12:34:56.00].)
| iex> {:ok, t1} = Time.new(12, 34, 56) |
| {:ok, ~T[12:34:56]} |
| iex> t2 = ~T[12:34:56.78] |
| ~T[12:34:56.78] |
| iex> t1 == t2 |
| false |
| iex> Time.add(t1, 3600) |
| ~T[13:34:56.000000] |
| iex> Time.add(t1, 3600, :millisecond) |
| ~T[12:34:59.600000] |
There are two date/time types: DateTime and NaiveDateTime. The naive version contains just a date and a time; DateTime adds the ability to associate a time zone. The ~N[...] sigil constructs NaiveDateTime structs.
If you are using dates and times in your code, you might want to augment these built-in types with a third-party library, such as Lau Taarnskov’s Calendar library.[6]