# Elixir v1.10.3 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` (see `Kernel.sigil_D/2`) 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 `t:Calendar.date/0` in their typespecs (instead of `t: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 third-party calendar libraries.

## Comparing dates

Comparisons in Elixir using `==/2`, `>/2`, `</2` 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

## Types

t()

## Functions

add(date, days)

Adds the number of days to the given `date`.

compare(date1, date2)

Compares two date structs.

convert(date, calendar)

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

convert!(date, calendar)

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

day_of_era(date)

Calculates the day-of-era and era for a given calendar `date`.

day_of_week(date)

Calculates the day of the week of a given `date`.

day_of_year(date)

Calculates the day of the year of a given `date`.

days_in_month(date)

Returns the number of days in the given `date` month.

diff(date1, date2)

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

from_erl(tuple, calendar \\ Calendar.ISO)

Converts an Erlang date tuple to a `Date` struct.

from_erl!(tuple, calendar \\ Calendar.ISO)

Converts an Erlang date tuple but raises for invalid dates.

from_iso8601(string, calendar \\ Calendar.ISO)

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

from_iso8601!(string, calendar \\ Calendar.ISO)

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

leap_year?(date)

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

months_in_year(date)

Returns the number of months in the given `date` year.

new(year, month, day, calendar \\ Calendar.ISO)

Builds a new ISO date.

quarter_of_year(date)

Calculates the quarter of the year of a given `date`.

range(first, last)

Returns a range of dates.

to_erl(date)

Converts the given `date` to an Erlang date tuple.

to_iso8601(date, format \\ :extended)

Converts the given `date` to ISO 8601:2004.

to_string(date)

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

utc_today(calendar \\ Calendar.ISO)

Returns the current date in UTC.

year_of_era(date)

Calculates the year-of-era and era for a given calendar year.

# Link to this section Types

Link to this type

# t()

View Source

## Specs

    t() :: %Date{
      calendar: Calendar.calendar(),
      day: Calendar.day(),
      month: Calendar.month(),
      year: Calendar.year()
    }

# Link to this section Functions

Link to this function

# add(date, days)

View Source (since 1.5.0)

## Specs

    add(Calendar.date(), integer()) :: t()

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]
    iex> Date.add(~D[-0010-01-01], -2)
    ~D[-0011-12-30]

Link to this function

# compare(date1, date2)

View Source (since 1.4.0)

## Specs

    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 (since 1.5.0)

## Specs

    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 (since 1.5.0)

## Specs

    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}

Link to this function

# day_of_era(date)

View Source (since 1.8.0)

## Specs

    day_of_era(Calendar.date()) :: {Calendar.day(), non_neg_integer()}

Calculates the day-of-era and era for a given calendar `date`.

Returns a tuple `{day, era}` representing the day within the era and the era number.

## Examples

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

    iex> Date.day_of_era(~D[0000-12-31])
    {1, 0}

Link to this function

# day_of_week(date)

View Source (since 1.4.0)

## Specs

    day_of_week(Calendar.date()) :: Calendar.day()

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
    iex> Date.day_of_week(~D[-0015-10-30])
    3

Link to this function

# day_of_year(date)

View Source (since 1.8.0)

## Specs

    day_of_year(Calendar.date()) :: Calendar.day()

Calculates the day of the year of a given `date`.

Returns the day of the year as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 366.

## Examples

    iex> Date.day_of_year(~D[2016-01-01])
    1
    iex> Date.day_of_year(~D[2016-11-01])
    306
    iex> Date.day_of_year(~D[-0015-10-30])
    303
    iex> Date.day_of_year(~D[2004-12-31])
    366

Link to this function

# days_in_month(date)

View Source (since 1.4.0)

## Specs

    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

Link to this function

# diff(date1, date2)

View Source (since 1.5.0)

## Specs

    diff(Calendar.date(), Calendar.date()) :: integer()

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[0000-01-02], ~D[-0001-12-30])
    3
    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

## Specs

    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

## Specs

    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

## Specs

    from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}

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

The year parsed by this function is limited to four digits.

## 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

## Specs

    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

Link to this function

# leap_year?(date)

View Source (since 1.4.0)

## Specs

    leap_year?(Calendar.date()) :: boolean()

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

# months_in_year(date)

View Source (since 1.7.0)

## Specs

    months_in_year(Calendar.date()) :: Calendar.month()

Returns the number of months in the given `date` year.

## Example

    iex> Date.months_in_year(~D[1900-01-13])
    12

Link to this function

# new(year, month, day, calendar \\ Calendar.ISO)

View Source

## Specs

    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}

Link to this function

# quarter_of_year(date)

View Source (since 1.8.0)

## Specs

    quarter_of_year(Calendar.date()) :: non_neg_integer()

Calculates the quarter of the year of a given `date`.

Returns the day of the year as an integer. For the ISO 8601 calendar (the default), it is an integer from 1 to 4.

## Examples

    iex> Date.quarter_of_year(~D[2016-10-31])
    4
    iex> Date.quarter_of_year(~D[2016-01-01])
    1
    iex> Date.quarter_of_year(~N[2016-04-01 01:23:45])
    2
    iex> Date.quarter_of_year(~D[-0015-09-30])
    3

Link to this function

# range(first, last)

View Source (since 1.5.0)

## Specs

    range(t(), t()) :: Date.Range.t()

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

Link to this function

# to_erl(date)

View Source

## Specs

    to_erl(Calendar.date()) :: :calendar.date()

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

## Specs

    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"

Link to this function

# to_string(date)

View Source

## Specs

    to_string(Calendar.date()) :: String.t()

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"
    iex> Date.to_string(~D[-0100-12-15])
    "-0100-12-15"

Link to this function

# utc_today(calendar \\ Calendar.ISO)

View Source (since 1.4.0)

## Specs

    utc_today(Calendar.calendar()) :: t()

Returns the current date in UTC.

## Examples

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

Link to this function

# year_of_era(date)

View Source (since 1.8.0)

## Specs

    year_of_era(Calendar.date()) :: {Calendar.year(), non_neg_integer()}

Calculates the year-of-era and era for a given calendar year.

Returns a tuple `{year, era}` representing the year within the era and the era number.

## Examples

    iex> Date.year_of_era(~D[0001-01-01])
    {1, 1}
    iex> Date.year_of_era(~D[0000-12-31])
    {1, 0}
    iex> Date.year_of_era(~D[-0001-01-01])
    {2, 0}