非常教程

Elixir 1.5参考手册

NaiveDateTime

NaiveDateTime

一个NaiveDateTime结构(不带时区)和函数。

NaiveDateTime结构包含字段年,月,日,小时,分钟,秒,微秒和日历。新天真的日期时间可以使用new/2new/7功能或使用~N印记来构建:

iex> ~N[2000-01-01 23:00:07]
~N[2000-01-01 23:00:07]

可以直接访问结构中的日期和时间字段:

iex> naive = ~N[2000-01-01 23:00:07]
iex> naive.year
2000
iex> naive.second
7

我们称他们为“天真”,因为这个日期时间表示没有时区。这意味着日期时间可能实际上并不存在于世界某些地区,即使它是有效的。

例如,当某个区域应用夏时制更改时,时钟通常向前或向后移动一个小时。这意味着某些日期时间永远不会发生,也可能不止发生一次。自NaiveDateTime如果没有针对时区进行验证,则这些错误将不会被注意到。

这个模块上的函数和NaiveDateTime结构以及任何包含与结构相同字段的NaiveDateTime结构一起工作,比如DateTime。这些函数期望Calendar.naive_datetime/0在它们的类型规范中(而不是t/0)。

开发人员应避免直接创建NaiveDateTime结构,而应依赖此模块提供的函数以及第三方日历库中的函数。

比较天真的日期时间

在药剂比较使用==><和类似的是结构以及基于所述NaiveDateTime结构字段。为了适当比较朴素的日期时间,请使用compare/2函数。

使用历元

add/3diff/3功能可以用于与日期时间的计算或检索的秒量中间人时刻。例如,如果有兴趣计算从Unix纪元(1970-01-01 00:00:00)开始的秒数:

iex> NaiveDateTime.diff(~N[2010-04-17 14:00:00], ~N[1970-01-01 00:00:00])
1271512800

iex> NaiveDateTime.add(~N[1970-01-01 00:00:00], 1271512800)
~N[2010-04-17 14:00:00]

这些函数经过优化以处理通用时期,例如上面的Unix Epoch或Gregorian Epoch(0000-01-01 00:00:00)。

类型

t()

功能

add(naive_datetime, integer, unit \ :second)

将指定的时间添加到NaiveDateTime

compare(naive_datetime1, naive_datetime2)

比较两个NaiveDateTime结构

convert(naive_datetime, calendar)

转换给定的naive_datetime从一个日历到另一个日历

convert!(naive_datetime, calendar)

转换给定的naive_datetime从一个日历到另一个日历

diff(naive_datetime1, naive_datetime2, unit \ :second)

减去naive_datetime2naive_datetime1

from_erl(tuple, microsecond \ {0, 0}, calendar \ Calendar.ISO)

将Erlang日期时间元组转换为NaiveDateTime结构

from_erl!(tuple, microsecond \ {0, 0})

将Erlang日期时间元组转换为NaiveDateTime结构体

from_iso8601(string, calendar \ Calendar.ISO)

解析ISO 8601:2004描述的扩展“日期和时间”格式

from_iso8601!(字符串,日历\ Calendar.ISO)

解析ISO 8601:2004描述的扩展“日期和时间”格式

new(date, time)

从日期和时间结构生成天真的日期时间。

new(year, month, day, hour, minute, second, microsecond \ {0, 0}, calendar \ Calendar.ISO)

构建一个新的ISO天真日期时间

to_date(naive_date_time)

NaiveDateTime转换成Date

to_erl(naive_datetime)

转换NaiveDateTime构造为Erlang日期时间元组。

to_iso8601(naive_datetime, format \ :extended)

将给定的天真日期时间转换为ISO 8601:2004

to_string(naive_datetime)

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

to_time(naive_date_time)

转换NaiveDateTimeTime

utc_now(calendar \ Calendar.ISO)

返回UTC中当前的天真日期时间。

t()

t() :: %NaiveDateTime{calendar: Calendar.calendar, day: Calendar.day, hour: Calendar.hour, microsecond: Calendar.microsecond, minute: Calendar.minute, month: Calendar.month, second: Calendar.second, year: Calendar.year}

add(naive_datetime, integer, unit \ :second)

add(t, integer, System.time_unit) :: t

为指定的时间添加一个指定的时间NaiveDateTime

接受integer任何unit可用的System.time_unit/0。负值将及时向后移动。

只有在两个日历都可以转换的情况下,此操作才有可能Calendar.ISO

实例

# adds seconds by default
iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], 2)
~N[2014-10-02 00:29:12]

# accepts negative offsets
iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], -2)
~N[2014-10-02 00:29:08]

# can work with other units
iex> NaiveDateTime.add(~N[2014-10-02 00:29:10], 2_000, :millisecond)
~N[2014-10-02 00:29:12]

# keeps the same precision
iex> NaiveDateTime.add(~N[2014-10-02 00:29:10.021], 21, :second)
~N[2014-10-02 00:29:31.021]

# changes below the precision will not be visible
iex> hidden = NaiveDateTime.add(~N[2014-10-02 00:29:10], 21, :millisecond)
iex> hidden.microsecond  # ~N[2014-10-02 00:29:10]
{21000, 0}

# from Gregorian seconds
iex> NaiveDateTime.add(~N[0000-01-01 00:00:00], 63579428950)
~N[2014-10-02 00:29:10]

compare(naive_datetime1, naive_datetime2)

compare(Calendar.naive_datetime, Calendar.naive_datetime) ::
  :lt |
  :eq |
  :gt

比较两NaiveDateTime结构。

:gt如果第一次晚于第二次,则返回:lt,反之亦然。如果两个NaiveDateTime相等:eq则返回。

实例

iex> NaiveDateTime.compare(~N[2016-04-16 13:30:15], ~N[2016-04-28 16:19:25])
:lt
iex> NaiveDateTime.compare(~N[2016-04-16 13:30:15.1], ~N[2016-04-16 13:30:15.01])
:gt

此函数还可用于比较没有时区信息的日期时间:

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> NaiveDateTime.compare(dt, ~N[2000-02-29 23:00:07])
:eq
iex> NaiveDateTime.compare(dt, ~N[2000-01-29 23:00:07])
:gt
iex> NaiveDateTime.compare(dt, ~N[2000-03-29 23:00:07])
:lt

convert(naive_datetime, calendar)

convert(Calendar.naive_datetime, Calendar.calendar) ::
  {:ok, t} |
  {:error, :incompatible_calendars}

转换给定的naive_datetime从一个日历到另一个日历。

如果无法在日历之间明确转换(请参阅Calendar.compatible_calendars?/2),{:error, :incompatible_calendars}则会返回一个元组。

实例

想象一下,有人实现Calendar.Holocene了一个基于公历日历的公历日历,该日历公历年正好增加了1万年:

iex> NaiveDateTime.convert(~N[2000-01-01 13:30:15], Calendar.Holocene)
{:ok, %NaiveDateTime{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1,
                     hour: 13, minute: 30, second: 15, microsecond: {0, 0}}}

convert!(naive_datetime, calendar)

convert!(Calendar.naive_datetime, Calendar.calendar) :: t

转换给定的naive_datetime从一个日历到另一个日历。

如果无法在日历之间明确转换(请参阅Calendar.compatible_calendars?/2参考资料),则会引发ArgumentError。

实例

想象一下,有人实现Calendar.Holocene了一个基于公历日历的公历日历,该日历公历年正好增加了1万年:

iex> NaiveDateTime.convert!(~N[2000-01-01 13:30:15], Calendar.Holocene)
%NaiveDateTime{calendar: Calendar.Holocene, year: 12000, month: 1, day: 1,
               hour: 13, minute: 30, second: 15, microsecond: {0, 0}}

diff(naive_datetime1, naive_datetime2, unit \ :second)

diff(t, t, System.time_unit) :: integer

减去naive_datetime2naive_datetime1

答案可以unit从任何可用的返回System.time_unit/0

此函数返回按秒测量秒数的差值Calendar.ISO

实例

iex> NaiveDateTime.diff(~N[2014-10-02 00:29:12], ~N[2014-10-02 00:29:10])
2
iex> NaiveDateTime.diff(~N[2014-10-02 00:29:12], ~N[2014-10-02 00:29:10], :microsecond)
2_000_000
iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10.042], ~N[2014-10-02 00:29:10.021], :millisecond)
21
iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10], ~N[2014-10-02 00:29:12])
-2

# to Gregorian seconds
iex> NaiveDateTime.diff(~N[2014-10-02 00:29:10], ~N[0000-01-01 00:00:00])
63579428950

from_erl(tuple, microsecond \ {0, 0}, calendar \ Calendar.ISO)

将Erlang日期时间元组转换为NaiveDateTime结构。

试图转换无效的ISO日历日期将产生错误元组。

实例

iex> NaiveDateTime.from_erl({{2000, 1, 1}, {13, 30, 15}})
{:ok, ~N[2000-01-01 13:30:15]}
iex> NaiveDateTime.from_erl({{2000, 1, 1}, {13, 30, 15}}, {5000, 3})
{:ok, ~N[2000-01-01 13:30:15.005]}
iex> NaiveDateTime.from_erl({{2000, 13, 1}, {13, 30, 15}})
{:error, :invalid_date}
iex> NaiveDateTime.from_erl({{2000, 13, 1},{13, 30, 15}})
{:error, :invalid_date}

from_erl!(tuple, microsecond \ {0, 0})

from_erl!(:calendar.datetime, Calendar.microsecond) ::
  t |
  no_return

将Erlang日期时间元组转换为NaiveDateTime结构。

如果日期时间无效,则引发。试图转换无效的ISO日历日期将产生错误元组。

实例

iex> NaiveDateTime.from_erl!({{2000, 1, 1}, {13, 30, 15}})
~N[2000-01-01 13:30:15]
iex> NaiveDateTime.from_erl!({{2000, 1, 1}, {13, 30, 15}}, {5000, 3})
~N[2000-01-01 13:30:15.005]
iex> NaiveDateTime.from_erl!({{2000, 13, 1}, {13, 30, 15}})
** (ArgumentError) cannot convert {{2000, 13, 1}, {13, 30, 15}} to naive datetime, reason: :invalid_date

from_iso8601(string, calendar \ Calendar.ISO)

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

解析ISO 8601:2004描述的扩展“日期和时间”格式。

时区偏移量可能包含在字符串中,但它们将被简单地丢弃,因为这些信息不包括在天真日期时间内。

根据标准的规定,如果需要,可以省略分隔符“T”,因为在该功能中没有歧义。

不支持精度较低的时间表示。

注意,虽然ISO 8601允许DateTime将24:00:00指定为次日的零小时,但Elixir不支持此表示法。

实例

iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07")
{:ok, ~N[2015-01-23 23:50:07]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07")
{:ok, ~N[2015-01-23 23:50:07]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07Z")
{:ok, ~N[2015-01-23 23:50:07]}

iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07.0")
{:ok, ~N[2015-01-23 23:50:07.0]}
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07,0123456")
{:ok, ~N[2015-01-23 23:50:07.012345]}
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07.0123456")
{:ok, ~N[2015-01-23 23:50:07.012345]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123Z")
{:ok, ~N[2015-01-23 23:50:07.123]}

iex> NaiveDateTime.from_iso8601("2015-01-23P23:50:07")
{:error, :invalid_format}
iex> NaiveDateTime.from_iso8601("2015:01:23 23-50-07")
{:error, :invalid_format}
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07A")
{:error, :invalid_format}
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:61")
{:error, :invalid_time}
iex> NaiveDateTime.from_iso8601("2015-01-32 23:50:07")
{:error, :invalid_date}

iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123+02:30")
{:ok, ~N[2015-01-23 23:50:07.123]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123+00:00")
{:ok, ~N[2015-01-23 23:50:07.123]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-02:30")
{:ok, ~N[2015-01-23 23:50:07.123]}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-00:00")
{:error, :invalid_format}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-00:60")
{:error, :invalid_format}
iex> NaiveDateTime.from_iso8601("2015-01-23T23:50:07.123-24:00")
{:error, :invalid_format}

from_iso8601!(string, calendar \ Calendar.ISO)

from_iso8601!(String.t, Calendar.calendar) :: t | no_return

解析ISO 8601:2004描述的扩展“日期和时间”格式。

如果格式无效,则引发。

实例

iex> NaiveDateTime.from_iso8601!("2015-01-23T23:50:07.123Z")
~N[2015-01-23 23:50:07.123]
iex> NaiveDateTime.from_iso8601!("2015-01-23T23:50:07,123Z")
~N[2015-01-23 23:50:07.123]
iex> NaiveDateTime.from_iso8601!("2015-01-23P23:50:07")
** (ArgumentError) cannot parse "2015-01-23P23:50:07" as naive datetime, reason: :invalid_format

new(date, time)

new(Date.t, Time.t) :: {:ok, t}

从日期和时间结构构建天真的日期时间。

实例

iex> NaiveDateTime.new(~D[2010-01-13], ~T[23:00:07.005])
{:ok, ~N[2010-01-13 23:00:07.005]}

new(year, month, day, hour, minute, second, microsecond \ {0, 0}, calendar \ Calendar.ISO)

new(Calendar.year, Calendar.month, Calendar.day, Calendar.hour, Calendar.minute, Calendar.second, Calendar.microsecond, Calendar.calendar) ::
  {:ok, t} |
  {:error, atom}

构建一个新的ISO天真日期时间。

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

实例

iex> NaiveDateTime.new(2000, 1, 1, 0, 0, 0)
{:ok, ~N[2000-01-01 00:00:00]}
iex> NaiveDateTime.new(2000, 13, 1, 0, 0, 0)
{:error, :invalid_date}
iex> NaiveDateTime.new(2000, 2, 29, 0, 0, 0)
{:ok, ~N[2000-02-29 00:00:00]}
iex> NaiveDateTime.new(2000, 2, 30, 0, 0, 0)
{:error, :invalid_date}
iex> NaiveDateTime.new(2001, 2, 29, 0, 0, 0)
{:error, :invalid_date}

iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, {0, 1})
{:ok, ~N[2000-01-01 23:59:59.0]}
iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, 999_999)
{:ok, ~N[2000-01-01 23:59:59.999999]}
iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 60, 999_999)
{:ok, ~N[2000-01-01 23:59:60.999999]}
iex> NaiveDateTime.new(2000, 1, 1, 24, 59, 59, 999_999)
{:error, :invalid_time}
iex> NaiveDateTime.new(2000, 1, 1, 23, 60, 59, 999_999)
{:error, :invalid_time}
iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 61, 999_999)
{:error, :invalid_time}
iex> NaiveDateTime.new(2000, 1, 1, 23, 59, 59, 1_000_000)
{:error, :invalid_time}

to_date(naive_date_time)

to_date(t) :: Date.t

NaiveDateTime转换成Date

因为Date不保存时间信息,数据将在转换过程中丢失。

实例

iex> NaiveDateTime.to_date(~N[2002-01-13 23:00:07])
~D[2002-01-13]

to_erl(naive_datetime)

to_erl(Calendar.time) :: :calendar.time
to_erl(t) :: :calendar.datetime

转换NaiveDateTime构造为Erlang日期时间元组。

只支持转换ISO日历中的天真日期时间,尝试从其他日历转换天真日期时间将引发。

警告:可能会出现精度下降,因为Erlang时间元组只存储小时/分钟/秒。

实例

iex> NaiveDateTime.to_erl(~N[2000-01-01 13:30:15])
{{2000, 1, 1}, {13, 30, 15}}

此函数还可用于将日期时间转换为不需要时区信息的ERL格式:

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> NaiveDateTime.to_erl(dt)
{{2000, 2, 29}, {23, 00, 07}}

to_iso8601(naive_datetime, format \ :extended)

to_iso8601(Calendar.naive_datetime, :basic | :extended) :: String.t

将给定的朴素日期时间转换为ISO 8601:2004。

默认情况下,NaiveDateTime.to_iso8601/2返回以“扩展”格式格式化的天真日期时间,以提高人们的可读性。它也通过传递:basic选项支持“基本”格式。

只支持转换ISO日历中的天真日期时间,尝试从其他日历转换天真日期时间将引发。

实例

iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13])
"2000-02-28T23:00:13"

iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13.001])
"2000-02-28T23:00:13.001"

iex> NaiveDateTime.to_iso8601(~N[2000-02-28 23:00:13.001], :basic)
"20000228T230013.001"

此函数还可用于在没有时区信息的情况下将日期时间转换为ISO 8601:

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> NaiveDateTime.to_iso8601(dt)
"2000-02-29T23:00:07"

to_string(naive_datetime)

to_string(Calendar.naive_datetime) :: String.t

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

实例

iex> NaiveDateTime.to_string(~N[2000-02-28 23:00:13])
"2000-02-28 23:00:13"
iex> NaiveDateTime.to_string(~N[2000-02-28 23:00:13.001])
"2000-02-28 23:00:13.001"

此函数还可用于将日期时间转换为没有时区信息的字符串:

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> NaiveDateTime.to_string(dt)
"2000-02-29 23:00:07"

to_time(naive_date_time)

to_time(t) :: Time.t

NaiveDateTime转换为Time

因为Time不保存日期信息,数据将在转换过程中丢失。

实例

iex> NaiveDateTime.to_time(~N[2002-01-13 23:00:07])
~T[23:00:07]

utc_now(calendar \ Calendar.ISO)

utc_now(Calendar.calendar) :: t

返回UTC中当前的天真日期时间。

更喜欢使用DateTime.utc_now/0在可能的情况下,相对于NaiveDateTime,它将保存时区信息。

实例

iex> naive_datetime = NaiveDateTime.utc_now()
iex> naive_datetime.year >= 2016
true

NaiveDateTime相关

Elixir 1.5

Elixir 基于 Erlang 虚拟机的函数式、面向并行,是一种较好的编程语言。它以 Erlang 为基础,支持分布式、高容错、实时应用程序的开发。

主页 https://elixir-lang.org/
源码 https://github.com/elixir-lang/elixir
版本 1.5
发布版本 1.5.2