檢視原始碼 日期 (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
結構相同的欄位的結構,例如 NaiveDateTime
和 DateTime
。此類函式會在類型規格中預期 Calendar.date/0
(而非 t/0
)。
開發人員應避免直接建立日期結構,而應依賴此模組提供的函式,以及第三方日曆函式庫中的函式。
比較日期
使用 ==/2
、>/2
、</2
等進行 Elixir 中的比較時,會根據結構和 Date
結構欄位進行比較。若要正確比較日期,請使用 compare/2
函式。此模組中 compare/2
函式的存在,也允許使用 Enum.min/2
和 Enum.max/2
函式取得 Enum
的最小和最大日期。例如
iex> Enum.min([~D[2017-03-31], ~D[2017-04-01]], Date)
~D[2017-03-31]
使用紀元
add/2
和 diff/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() }
函式
@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]
@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
@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
@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]
@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]
@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
@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}}
@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}
@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}
@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
@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
@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
@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
@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]
@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]
@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}
@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
@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]
@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}
@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
@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
@spec months_in_year(Calendar.date()) :: Calendar.month()
傳回指定 date
年份中的月份數。
範例
iex> Date.months_in_year(~D[1900-01-13])
12
@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}
@spec new!(Calendar.year(), Calendar.month(), Calendar.day(), Calendar.calendar()) :: t()
建立新的 ISO 日期。
預期所有值都是整數。如果每個輸入符合適當的範圍,則傳回 日期
,如果日期無效,則會引發錯誤。
範例
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]
@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
@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]]
@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}
@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
@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"
@spec utc_today(Calendar.calendar()) :: t()
傳回 UTC 中的目前日期。
範例
iex> date = Date.utc_today()
iex> date.year >= 2016
true
@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}