Elixir v1.7.4 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 ==/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
Functions
Adds the number of days to the given date
Compares two date structs
Similar to Date.convert/2
, but raises an ArgumentError
if the conversion between the two calendars is not possible
Converts the given date
from its calendar to the given calendar
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 but raises for invalid dates
Converts an Erlang date tuple to a Date
struct
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 the number of months in the given date
year
Builds a new ISO date
Returns a range of dates
Converts the given date
to an Erlang date tuple
Converts the given date
to
ISO 8601:2004
Converts the given date to a string according to its calendar
Returns the current date in UTC
Link to this section Types
t() :: %Date{ calendar: Calendar.calendar(), day: Calendar.day(), month: Calendar.month(), year: Calendar.year() }
Link to this section Functions
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]
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
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}
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}}
day_of_week(Calendar.date()) :: non_neg_integer()
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
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
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
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
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}
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
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}
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
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
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}
range(Date.t(), Date.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
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}
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"
iex> Date.to_string(~D[-0100-12-15])
"-0100-12-15"
utc_today(Calendar.calendar()) :: t()
Returns the current date in UTC.
Examples
iex> date = Date.utc_today()
iex> date.year >= 2016
true