Elixir v1.6.1 Date View Source

A Date struct and functions.

The Date struct contains the fields year, month, day and calendar. New dates can be built with the new/3 function or using the ~D sigil:

iex> ~D[2000-01-01]
~D[2000-01-01]

Both new/3 and sigil return a struct where the date fields can be accessed directly:

iex> date = ~D[2000-01-01]
iex> date.year
2000
iex> date.month
1

The functions on this module work with the Date struct as well as any struct that contains the same fields as the Date struct, such as NaiveDateTime and DateTime. Such functions expect Calendar.date/0 in their typespecs (instead of t/0).

Developers should avoid creating the Date structs directly and instead rely on the functions provided by this module as well as the ones in 3rd party calendar libraries.

Comparing dates

Comparisons in Elixir using ==, >, < and similar are structural and based on the Date struct fields. For proper comparison between dates, use the compare/2 function.

Using epochs

The add/2 and diff/2 functions can be used for computing dates or retrieving the number of days between instants. For example, if there is an interest in computing the number of days from the Unix epoch (1970-01-01):

iex> Date.diff(~D[2010-04-17], ~D[1970-01-01])
14716

iex> Date.add(~D[1970-01-01], 14716)
~D[2010-04-17]

Those functions are optimized to deal with common epochs, such as the Unix Epoch above or the Gregorian Epoch (0000-01-01).

Link to this section Summary

Functions

Adds the number of days to the given date

Compares two date structs

Converts the given date from its calendar to the given calendar

Similar to Date.convert/2, but raises an ArgumentError if the conversion between the two calendars is not possible

Calculates the day of the week of a given date

Returns the number of days in the given date month

Calculates the difference between two dates, in a full number of days

Converts an Erlang date tuple to a Date struct

Converts an Erlang date tuple but raises for invalid dates

Parses the extended “Dates” format described by ISO 8601:2004

Parses the extended “Dates” format described by ISO 8601:2004

Returns true if the year in the given date is a leap year

Returns a range of dates

Converts the given date to an Erlang date tuple

Converts the given date to a string according to its calendar

Returns the current date in UTC

Link to this section Types

Link to this type t() View Source
t() :: %Date{
  calendar: Calendar.calendar(),
  day: Calendar.day(),
  month: Calendar.month(),
  year: Calendar.year()
}

Link to this section Functions

Adds the number of days to the given date.

The days are counted as Gregorian days. The date is returned in the same calendar as it was given in.

Examples

iex> Date.add(~D[2000-01-03], -2)
~D[2000-01-01]
iex> Date.add(~D[2000-01-01], 2)
~D[2000-01-03]

iex> Date.add(~N[2000-01-01 09:00:00], 2)
~D[2000-01-03]
Link to this function compare(date1, date2) View Source
compare(Calendar.date(), Calendar.date()) :: :lt | :eq | :gt

Compares two date structs.

Returns :gt if first date is later than the second and :lt for vice versa. If the two dates are equal :eq is returned.

Examples

iex> Date.compare(~D[2016-04-16], ~D[2016-04-28])
:lt

This function can also be used to compare across more complex calendar types by considering only the date fields:

iex> Date.compare(~D[2016-04-16], ~N[2016-04-28 01:23:45])
:lt
iex> Date.compare(~D[2016-04-16], ~N[2016-04-16 01:23:45])
:eq
iex> Date.compare(~N[2016-04-16 12:34:56], ~N[2016-04-16 01:23:45])
:eq
Link to this function convert(date, calendar) View Source
convert(Calendar.date(), Calendar.calendar()) ::
  {:ok, t()} | {:error, :incompatible_calendars}

Converts the given date from its calendar to the given calendar.

Returns {:ok, date} if the calendars are compatible, or {:error, :incompatible_calendars} if they are not.

See also Calendar.compatible_calendars?/2.

Examples

Imagine someone implements Calendar.Holocene, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year:

iex> Date.convert(~D[2000-01-01], Calendar.Holocene)
{:ok, %Date{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1}}
Link to this function convert!(date, calendar) View Source
convert!(Calendar.date(), Calendar.calendar()) :: t()

Similar to Date.convert/2, but raises an ArgumentError if the conversion between the two calendars is not possible.

Examples

Imagine someone implements Calendar.Holocene, a calendar based on the Gregorian calendar that adds exactly 10,000 years to the current Gregorian year:

iex> Date.convert!(~D[2000-01-01], Calendar.Holocene)
%Date{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1}

Calculates the day of the week of a given date.

Returns the day of the week as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 7, where 1 is Monday and 7 is Sunday.

Examples

iex> Date.day_of_week(~D[2016-10-31])
1
iex> Date.day_of_week(~D[2016-11-01])
2
iex> Date.day_of_week(~N[2016-11-01 01:23:45])
2
Link to this function days_in_month(date) View Source
days_in_month(Calendar.date()) :: Calendar.day()

Returns the number of days in the given date month.

Examples

iex> Date.days_in_month(~D[1900-01-13])
31
iex> Date.days_in_month(~D[1900-02-09])
28
iex> Date.days_in_month(~N[2000-02-20 01:23:45])
29

Calculates the difference between two dates, in a full number of days.

It returns the number of Gregorian days between the dates. Only Date structs that follow the same or compatible calendars can be compared this way. If two calendars are not compatible, it will raise.

Examples

iex> Date.diff(~D[2000-01-03], ~D[2000-01-01])
2
iex> Date.diff(~D[2000-01-01], ~D[2000-01-03])
-2

iex> Date.diff(~D[2000-01-01], ~N[2000-01-03 09:00:00])
-2
Link to this function from_erl(tuple, calendar \\ Calendar.ISO) View Source
from_erl(:calendar.date(), Calendar.calendar()) ::
  {:ok, t()} | {:error, atom()}

Converts an Erlang date tuple to a Date struct.

Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will return an error tuple.

Examples

iex> Date.from_erl({2000, 1, 1})
{:ok, ~D[2000-01-01]}
iex> Date.from_erl({2000, 13, 1})
{:error, :invalid_date}
Link to this function from_erl!(tuple, calendar \\ Calendar.ISO) View Source
from_erl!(:calendar.date(), Calendar.calendar()) :: t()

Converts an Erlang date tuple but raises for invalid dates.

Examples

iex> Date.from_erl!({2000, 1, 1})
~D[2000-01-01]
iex> Date.from_erl!({2000, 13, 1})
** (ArgumentError) cannot convert {2000, 13, 1} to date, reason: :invalid_date
Link to this function from_iso8601(string, calendar \\ Calendar.ISO) View Source
from_iso8601(String.t(), Calendar.calendar()) ::
  {:ok, t()} | {:error, atom()}

Parses the extended “Dates” format described by ISO 8601:2004.

Examples

iex> Date.from_iso8601("2015-01-23")
{:ok, ~D[2015-01-23]}

iex> Date.from_iso8601("2015:01:23")
{:error, :invalid_format}

iex> Date.from_iso8601("2015-01-32")
{:error, :invalid_date}
Link to this function from_iso8601!(string, calendar \\ Calendar.ISO) View Source
from_iso8601!(String.t(), Calendar.calendar()) :: t()

Parses the extended “Dates” format described by ISO 8601:2004.

Raises if the format is invalid.

Examples

iex> Date.from_iso8601!("2015-01-23")
~D[2015-01-23]
iex> Date.from_iso8601!("2015:01:23")
** (ArgumentError) cannot parse "2015:01:23" as date, reason: :invalid_format

Returns true if the year in the given date is a leap year.

Examples

iex> Date.leap_year?(~D[2000-01-01])
true
iex> Date.leap_year?(~D[2001-01-01])
false
iex> Date.leap_year?(~D[2004-01-01])
true
iex> Date.leap_year?(~D[1900-01-01])
false
iex> Date.leap_year?(~N[2004-01-01 01:23:45])
true
Link to this function new(year, month, day, calendar \\ Calendar.ISO) View Source
new(Calendar.year(), Calendar.month(), Calendar.day(), Calendar.calendar()) ::
  {:ok, t()} | {:error, atom()}

Builds a new ISO date.

Expects all values to be integers. Returns {:ok, date} if each entry fits its appropriate range, returns {:error, reason} otherwise.

Examples

iex> Date.new(2000, 1, 1)
{:ok, ~D[2000-01-01]}
iex> Date.new(2000, 13, 1)
{:error, :invalid_date}
iex> Date.new(2000, 2, 29)
{:ok, ~D[2000-02-29]}

iex> Date.new(2000, 2, 30)
{:error, :invalid_date}
iex> Date.new(2001, 2, 29)
{:error, :invalid_date}

Returns a range of dates.

A range of dates represents a discrete number of dates where the first and last values are dates with matching calendars.

Ranges of dates can be either increasing (first <= last) or decreasing (first > last). They are also always inclusive.

Examples

iex> Date.range(~D[1999-01-01], ~D[2000-01-01])
#DateRange<~D[1999-01-01], ~D[2000-01-01]>

A range of dates implements the Enumerable protocol, which means functions in the Enum module can be used to work with ranges:

iex> range = Date.range(~D[2001-01-01], ~D[2002-01-01])
iex> Enum.count(range)
366
iex> Enum.member?(range, ~D[2001-02-01])
true
iex> Enum.reduce(range, 0, fn _date, acc -> acc - 1 end)
-366

Converts the given date to an Erlang date tuple.

Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will raise.

Examples

iex> Date.to_erl(~D[2000-01-01])
{2000, 1, 1}

iex> Date.to_erl(~N[2000-01-01 00:00:00])
{2000, 1, 1}
Link to this function to_iso8601(date, format \\ :extended) View Source
to_iso8601(Calendar.date(), :extended | :basic) :: String.t()

Converts the given date to ISO 8601:2004.

By default, Date.to_iso8601/2 returns dates formatted in the “extended” format, for human readability. It also supports the “basic” format through passing the :basic option.

Only supports converting dates which are in the ISO calendar, or other calendars in which the days also start at midnight. Attempting to convert dates from other calendars will raise an ArgumentError.

Examples

iex> Date.to_iso8601(~D[2000-02-28])
"2000-02-28"

iex> Date.to_iso8601(~D[2000-02-28], :basic)
"20000228"

iex> Date.to_iso8601(~N[2000-02-28 00:00:00])
"2000-02-28"

Converts the given date to a string according to its calendar.

Examples

iex> Date.to_string(~D[2000-02-28])
"2000-02-28"
iex> Date.to_string(~N[2000-02-28 01:23:45])
"2000-02-28"
Link to this function utc_today(calendar \\ Calendar.ISO) View Source
utc_today(Calendar.calendar()) :: t()

Returns the current date in UTC.

Examples

iex> date = Date.utc_today()
iex> date.year >= 2016
true