查看源代码 Date (Elixir v1.16.2)

日期结构体和函数。

日期结构体包含年、月、日和日历字段。可以使用 new/3 函数或 ~D(参见 sigil_D/2)符号创建新的日期

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

new/3 函数和符号都会返回一个结构体,其中可以访问日期字段。

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

此模块中的函数适用于 Date 结构体,以及任何包含与 Date 结构体相同字段的结构体,例如 NaiveDateTimeDateTime。这些函数在类型说明中使用 Calendar.date/0(而不是 t/0)。

开发者应该避免直接创建日期结构体,而是应该依赖此模块提供的函数以及第三方日历库提供的函数。

比较日期

Elixir 中使用 ==/2>/2</2 和类似的比较是结构性的,基于 Date 结构体的字段。要正确比较日期,请使用 compare/2 函数。此模块中 compare/2 函数的存在也允许使用 Enum.min/2Enum.max/2 函数来获取 Enum 中的最小和最大日期。例如

iex>  Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date)
~D[2017-03-31]

使用纪元

add/2diff/2 函数可用于计算日期或检索时间间隔之间的天数。例如,如果想计算从 Unix 纪元(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]

这些函数经过优化,可以处理常见的纪元,例如上面的 Unix 纪元或公历纪元(0000-01-01)。

摘要

函数

将天数添加到给定的 date

如果第一个日期严格晚于第二个日期,则返回 true

如果第一个日期严格早于第二个日期,则返回 true

计算给定 date 的月份第一天对应的日期。

计算给定 date 的星期第一天对应的日期。

比较两个日期结构体。

将给定的 date 从其日历转换为给定的 calendar

类似于 Date.convert/2,但如果两个日历之间的转换不可行,则会引发 ArgumentError

计算给定日历 date 的纪元日和纪元。

计算给定 date 的星期几。

计算给定 date 的一年中的第几天。

返回给定 date 月份的天数。

计算两个日期之间的差值,以完整的天数表示。

计算给定 date 的月份最后一天对应的日期。

计算给定 date 的星期最后一天对应的日期。

将 Erlang 日期元组转换为 Date 结构体。

将 Erlang 日期元组转换为,但对于无效日期会引发异常。

将公历天数转换为 Date 结构体。

解析 ISO 8601:2019 中描述的扩展“日期”格式。

解析 ISO 8601:2019 中描述的扩展“日期”格式。

如果给定 date 的年份是闰年,则返回 true

返回给定 date 年份的月份数。

构建一个新的 ISO 日期。

构建一个新的 ISO 日期。

计算给定 date 的一年中的季度。

返回一个日期范围。

返回具有步长的日期范围。

将给定的 date 转换为 Erlang 日期元组。

date 结构体转换为公历天数。

将给定的 date 转换为 ISO 8601:2019

根据其日历将给定的日期转换为字符串。

返回当前的 UTC 日期。

计算给定日历年份的纪元年和纪元。

类型

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

函数

链接到此函数

add(date, days)

查看源代码 (自 1.5.0 版本起)
@spec add(Calendar.date(), integer()) :: t()

将天数添加到给定的 date

天数按公历天数计算。返回的日期与输入的日期使用相同的日历。

示例

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]
链接到此函数

after?(date1, date2)

查看源代码 (自 1.15.0 版本起)
@spec after?(Calendar.date(), Calendar.date()) :: boolean()

如果第一个日期严格晚于第二个日期,则返回 true

示例

iex> Date.after?(~D[2022-02-02], ~D[2021-01-01])
true
iex> Date.after?(~D[2021-01-01], ~D[2021-01-01])
false
iex> Date.after?(~D[2021-01-01], ~D[2022-02-02])
false
链接到此函数

before?(date1, date2)

查看源代码 (自 1.15.0 版本起)
@spec before?(Calendar.date(), Calendar.date()) :: boolean()

如果第一个日期严格早于第二个日期,则返回 true

示例

iex> Date.before?(~D[2021-01-01], ~D[2022-02-02])
true
iex> Date.before?(~D[2021-01-01], ~D[2021-01-01])
false
iex> Date.before?(~D[2022-02-02], ~D[2021-01-01])
false
链接到此函数

beginning_of_month(date)

查看源代码 (自 1.11.0 版本起)
@spec beginning_of_month(Calendar.date()) :: t()

计算给定 date 的月份第一天对应的日期。

示例

iex> Date.beginning_of_month(~D[2000-01-31])
~D[2000-01-01]
iex> Date.beginning_of_month(~D[2000-01-01])
~D[2000-01-01]
iex> Date.beginning_of_month(~N[2000-01-31 01:23:45])
~D[2000-01-01]
链接到此函数

beginning_of_week(date, starting_on \\ :default)

查看源代码 (自 1.11.0 版本起)
@spec beginning_of_week(Calendar.date(), starting_on :: :default | atom()) :: t()

计算给定 date 的星期第一天对应的日期。

如果日期已经是星期第一天,则返回该日期本身。对于内置的 ISO 日历,星期从周一算起。可以将星期几而不是 :default 作为 starting_on 参数。

示例

iex> Date.beginning_of_week(~D[2020-07-11])
~D[2020-07-06]
iex> Date.beginning_of_week(~D[2020-07-06])
~D[2020-07-06]
iex> Date.beginning_of_week(~D[2020-07-11], :sunday)
~D[2020-07-05]
iex> Date.beginning_of_week(~D[2020-07-11], :saturday)
~D[2020-07-11]
iex> Date.beginning_of_week(~N[2020-07-11 01:23:45])
~D[2020-07-06]
链接到此函数

compare(date1, date2)

查看源代码 (自 1.4.0 版本起)
@spec compare(Calendar.date(), Calendar.date()) :: :lt | :eq | :gt

比较两个日期结构体。

如果第一个日期晚于第二个日期,则返回 :gt;反之则返回 :lt。如果两个日期相等,则返回 :eq

示例

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

此函数还可以用于比较更复杂的日历类型,方法是只考虑日期字段

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(date, calendar)

查看源代码 (自 1.5.0 版本起)
@spec convert(Calendar.date(), Calendar.calendar()) ::
  {:ok, t()} | {:error, :incompatible_calendars}

将给定的 date 从其日历转换为给定的 calendar

如果日历兼容,则返回 {:ok, date};如果不兼容,则返回 {:error, :incompatible_calendars}

另请参见 Calendar.compatible_calendars?/2

示例

假设有人实现了 Calendar.Holocene,这是一个基于公历的日历,它将当前公历年份增加 10,000 年

iex> Date.convert(~D[2000-01-01], Calendar.Holocene)
{:ok, %Date{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1}}
链接到此函数

convert!(date, calendar)

查看源代码 (自 1.5.0 版本起)
@spec convert!(Calendar.date(), Calendar.calendar()) :: t()

类似于 Date.convert/2,但如果两个日历之间的转换不可行,则会引发 ArgumentError

示例

假设有人实现了 Calendar.Holocene,这是一个基于公历的日历,它将当前公历年份增加 10,000 年

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

day_of_era(date)

查看源代码 (自 1.8.0 版本起)
@spec day_of_era(Calendar.date()) :: {Calendar.day(), non_neg_integer()}

计算给定日历 date 的纪元日和纪元。

返回一个元组 {day, era},它表示纪元中的日期和纪元编号。

示例

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

iex> Date.day_of_era(~D[0000-12-31])
{1, 0}
链接到此函数

day_of_week(date, starting_on \\ :default)

查看源代码 (自 1.4.0 版本起)
@spec day_of_week(Calendar.date(), starting_on :: :default | atom()) ::
  Calendar.day_of_week()

计算给定 date 的星期几。

将星期几作为整数返回。对于 ISO 8601 日历(默认),它是一个从 1 到 7 的整数,其中 1 是周一,7 是周日。

可以提供一个可选的 starting_on 值,它配置星期开始的星期几。它的默认值为 :default,对于内置的 ISO 日历,它对应于 :monday。可以提供任何其他星期几。

示例

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

iex> Date.day_of_week(~D[2016-10-31], :sunday)
2
iex> Date.day_of_week(~D[2016-11-01], :sunday)
3
iex> Date.day_of_week(~N[2016-11-01 01:23:45], :sunday)
3
iex> Date.day_of_week(~D[-0015-10-30], :sunday)
4
链接到此函数

day_of_year(date)

查看源代码 (自 1.8.0 版本起)
@spec day_of_year(Calendar.date()) :: Calendar.day()

计算给定 date 的一年中的第几天。

将一年中的第几天作为整数返回。对于 ISO 8601 日历(默认),它是一个从 1 到 366 的整数。

示例

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
链接到此函数

days_in_month(date)

查看源代码 (自 1.4.0 版本起)
@spec days_in_month(Calendar.date()) :: Calendar.day()

返回给定 date 月份的天数。

示例

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(date1, date2)

查看源代码 (自 1.5.0 版本起)
@spec diff(Calendar.date(), Calendar.date()) :: integer()

计算两个日期之间的差值,以完整的天数表示。

它返回两个日期之间的格里高利日数。仅当两个 Date 结构遵循相同或兼容的日历时,才能以这种方式进行比较。如果两个日历不兼容,它将引发错误。

示例

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
链接到此函数

end_of_month(date)

查看源代码 (自 1.11.0 版本起)
@spec end_of_month(Calendar.date()) :: t()

计算给定 date 的月份最后一天对应的日期。

示例

iex> Date.end_of_month(~D[2000-01-01])
~D[2000-01-31]
iex> Date.end_of_month(~D[2000-01-31])
~D[2000-01-31]
iex> Date.end_of_month(~N[2000-01-01 01:23:45])
~D[2000-01-31]
链接到此函数

end_of_week(date, starting_on \\ :default)

查看源代码 (自 1.11.0 版本起)
@spec end_of_week(Calendar.date(), starting_on :: :default | atom()) :: t()

计算给定 date 的星期最后一天对应的日期。

如果该日已经是该周的最后一天,则返回该日本身。对于内置的 ISO 日历,一周以周日结束。可以给出工作日而不是 :default 作为 starting_on

示例

iex> Date.end_of_week(~D[2020-07-11])
~D[2020-07-12]
iex> Date.end_of_week(~D[2020-07-05])
~D[2020-07-05]
iex> Date.end_of_week(~D[2020-07-06], :sunday)
~D[2020-07-11]
iex> Date.end_of_week(~D[2020-07-06], :saturday)
~D[2020-07-10]
iex> Date.end_of_week(~N[2020-07-11 01:23:45])
~D[2020-07-12]
链接到此函数

from_erl(tuple, calendar \\ Calendar.ISO)

查看源代码
@spec from_erl(:calendar.date(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}

将 Erlang 日期元组转换为 Date 结构体。

仅支持转换处于 ISO 日历中的日期,或其他日历,其中日期也从午夜开始。尝试转换来自其他日历的日期将返回一个错误元组。

示例

iex> Date.from_erl({2000, 1, 1})
{:ok, ~D[2000-01-01]}
iex> Date.from_erl({2000, 13, 1})
{:error, :invalid_date}
链接到此函数

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

查看源代码
@spec from_erl!(:calendar.date(), Calendar.calendar()) :: t()

将 Erlang 日期元组转换为,但对于无效日期会引发异常。

示例

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_gregorian_days(days, calendar \\ Calendar.ISO)

查看源代码 (自 1.11.0 版本起)
@spec from_gregorian_days(integer(), Calendar.calendar()) :: t()

将公历天数转换为 Date 结构体。

示例

iex> Date.from_gregorian_days(1)
~D[0000-01-02]
iex> Date.from_gregorian_days(730_485)
~D[2000-01-01]
iex> Date.from_gregorian_days(-1)
~D[-0001-12-31]
链接到此函数

from_iso8601(string, calendar \\ Calendar.ISO)

查看源代码
@spec from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t()} | {:error, atom()}

解析 ISO 8601:2019 中描述的扩展“日期”格式。

此函数解析的年份限制为四位数字。

示例

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}
链接到此函数

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

查看源代码
@spec from_iso8601!(String.t(), Calendar.calendar()) :: t()

解析 ISO 8601:2019 中描述的扩展“日期”格式。

如果格式无效,则会引发错误。

示例

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
链接到此函数

leap_year?(date)

查看源代码 (自 1.4.0 版本起)
@spec leap_year?(Calendar.date()) :: boolean()

如果给定 date 的年份是闰年,则返回 true

示例

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(date)

查看源代码 (自 1.7.0 版本起)
@spec months_in_year(Calendar.date()) :: Calendar.month()

返回给定 date 年份的月份数。

示例

iex> Date.months_in_year(~D[1900-01-13])
12
链接到此函数

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

查看源代码
@spec new(Calendar.year(), Calendar.month(), Calendar.day(), Calendar.calendar()) ::
  {:ok, t()} | {:error, atom()}

构建一个新的 ISO 日期。

期望所有值都是整数。如果每个条目都符合其适当的范围,则返回 {:ok, date},否则返回 {:error, reason}

示例

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}
链接到此函数

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

查看源代码 (自 1.11.0 版本起)

构建一个新的 ISO 日期。

期望所有值都是整数。如果每个条目都符合其适当的范围,则返回 date,如果日期无效,则会引发错误。

示例

iex> Date.new!(2000, 1, 1)
~D[2000-01-01]
iex> Date.new!(2000, 13, 1)
** (ArgumentError) cannot build date, reason: :invalid_date
iex> Date.new!(2000, 2, 29)
~D[2000-02-29]
链接到此函数

quarter_of_year(date)

查看源代码 (自 1.8.0 版本起)
@spec quarter_of_year(Calendar.date()) :: non_neg_integer()

计算给定 date 的一年中的季度。

返回一年中的第几天作为整数。对于 ISO 8601 日历(默认值),它是 1 到 4 之间的整数。

示例

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
链接到此函数

range(first, last)

查看源代码 (自 1.5.0 版本起)
@spec range(Calendar.date(), Calendar.date()) :: Date.Range.t()

返回一个日期范围。

日期范围表示一组离散的日期,其中第一个和最后一个值是具有匹配日历的日期。

日期范围可以是递增的 (first <= last) 并且总是包含边界。对于递减范围,请使用 range/3,并将 -1 作为步长作为第一个参数。

示例

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

日期范围实现了 Enumerable 协议,这意味着 Enum 模块中的函数可以用于处理范围

iex> range = Date.range(~D[2001-01-01], ~D[2002-01-01])
iex> range
Date.range(~D[2001-01-01], ~D[2002-01-01])
iex> Enum.count(range)
366
iex> ~D[2001-02-01] in range
true
iex> Enum.take(range, 3)
[~D[2001-01-01], ~D[2001-01-02], ~D[2001-01-03]]
链接到此函数

range(first, last, step)

查看源代码 (自 1.12.0 版本起)
@spec range(Calendar.date(), Calendar.date(), step :: pos_integer() | neg_integer()) ::
  Date.Range.t()

返回具有步长的日期范围。

示例

iex> range = Date.range(~D[2001-01-01], ~D[2002-01-01], 2)
iex> range
Date.range(~D[2001-01-01], ~D[2002-01-01], 2)
iex> Enum.count(range)
183
iex> ~D[2001-01-03] in range
true
iex> Enum.take(range, 3)
[~D[2001-01-01], ~D[2001-01-03], ~D[2001-01-05]]
@spec to_erl(Calendar.date()) :: :calendar.date()

将给定的 date 转换为 Erlang 日期元组。

仅支持转换处于 ISO 日历中的日期,或其他日历,其中日期也从午夜开始。尝试转换来自其他日历的日期将引发错误。

示例

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_gregorian_days(date)

查看源代码 (自 1.11.0 版本起)
@spec to_gregorian_days(Calendar.date()) :: integer()

date 结构体转换为公历天数。

示例

iex> Date.to_gregorian_days(~D[0000-01-02])
1
iex> Date.to_gregorian_days(~D[2000-01-01])
730_485
iex> Date.to_gregorian_days(~N[2000-01-01 00:00:00])
730_485
链接到此函数

to_iso8601(date, format \\ :extended)

查看源代码
@spec to_iso8601(Calendar.date(), :extended | :basic) :: String.t()

将给定的 date 转换为 ISO 8601:2019

默认情况下,Date.to_iso8601/2 以“扩展”格式返回日期,以便于人类阅读。它还支持通过传递 :basic 选项的“基本”格式。

仅支持转换处于 ISO 日历中的日期,或其他日历,其中日期也从午夜开始。尝试转换来自其他日历的日期将引发一个 ArgumentError 错误。

示例

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"
@spec to_string(Calendar.date()) :: String.t()

根据其日历将给定的日期转换为字符串。

示例

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.ISO)

查看源代码 (自 1.4.0 版本起)
@spec utc_today(Calendar.calendar()) :: t()

返回当前的 UTC 日期。

示例

iex> date = Date.utc_today()
iex> date.year >= 2016
true
链接到此函数

year_of_era(date)

查看源代码 (自 1.8.0 版本起)
@spec year_of_era(Calendar.date()) :: {Calendar.year(), non_neg_integer()}

计算给定日历年份的纪元年和纪元。

返回一个元组 {year, era},表示纪元中的年份和纪元号。

示例

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}