首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

日期时间 | DateTime

带有时区的datetime实现。

这个日期时间可以看作给定时区的日期时间的短暂快照。出于此目的,它还包括UTC和标准偏移量,以及专用于格式化目的的区域缩写字段。

请记住,使用药剂比较==><和朋友是结构性的,并根据日期时间结构域。为了适当比较日期时间,请使用该compare/2功能。

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

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

我的函数在哪里?

你会注意到这个模块只包含转换函数以及在UTC上工作的函数。这是因为适当的DateTime实现需要一个TimeZone数据库,该数据库目前不作为Elixir的一部分提供。

这可以在即将到来的版本中解决,同时,使用第三方包提供DateTime构建和类似的功能以及时区支持。

类型

t()

函数

比较(datetime1,datetime2)

比较两个日期时间结构

转换(日期时间,日历)

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

转换!(日期时间,日历)

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

diff(datetime1,datetime2,unit \:second)

减去datetime2datetime1

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

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

from_naive(naive_datetime,time_zone)

转换给定的NaiveDateTimeDateTime

from_naive!(naive_datetime,time_zone)

转换给定的NaiveDateTimeDateTime

from_unix(整数,单位\:秒,日历\ Calendar.ISO)

将给定的unix时间转换为DateTime

from_unix!(整数,单位\:秒,日历\ Calendar.ISO)

将给定的unix时间转换为DateTime

到[医]日期%28日期[医]时间%29

将a转换DateTimeDate

to_iso8601(日期时间,格式\:扩展)

将给定的日期时间转换为ISO 8601:2004格式

to_naive(DATE_TIME)

转换给定的datetime变成NaiveDateTime

to_string(日期时间)

转换给定的datetime根据其日历调整为字符串。

TO_TIME(DATE_TIME)

转换DateTimeTime

to_unix(日期时间,单位\:秒)

转换给定的datetime到Unix时间

utc_now(日历\ Calendar.ISO)

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

t()

代码语言:javascript
复制
t() :: %DateTime{calendar: Calendar.calendar, day: Calendar.day, hour: Calendar.hour, microsecond: Calendar.microsecond, minute: Calendar.minute, month: Calendar.month, second: Calendar.second, std_offset: Calendar.std_offset, time_zone: Calendar.time_zone, utc_offset: Calendar.utc_offset, year: Calendar.year, zone_abbr: Calendar.zone_abbr}

compare(datetime1, datetime2)

代码语言:javascript
复制
compare(Calendar.datetime, Calendar.datetime) :: :lt | :eq | :gt

比较两个日期时间结构。

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

请注意,在进行比较时,UTC和STC偏移都将被考虑在内。

实例

代码语言:javascript
复制
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                 hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                 utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> dt2 = %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> DateTime.compare(dt1, dt2)
:gt

convert(datetime, calendar)

代码语言:javascript
复制
convert(Calendar.datetime, Calendar.calendar) ::
  {:ok, t} |
  {:error, :incompatible_calendars}

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

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

实例

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

代码语言:javascript
复制
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                 hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                 utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.convert(dt1, Calendar.Holocene)
{:ok, %DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
                microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
                time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
                zone_abbr: "AMT"}}

转换!(日期时间,日历)

代码语言:javascript
复制
convert!(Calendar.datetime, Calendar.calendar) ::
  t |
  no_return

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

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

实例

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

代码语言:javascript
复制
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                 hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                 utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.convert!(dt1, Calendar.Holocene)
%DateTime{calendar: Calendar.Holocene, day: 29, hour: 23,
          microsecond: {0, 0}, minute: 0, month: 2, second: 7, std_offset: 0,
          time_zone: "America/Manaus", utc_offset: -14400, year: 12000,
          zone_abbr: "AMT"}

diff(datetime1, datetime2, unit \ :second)

减去datetime2datetime1

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

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

实例

代码语言:javascript
复制
iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                 hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                 utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> dt2 = %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> DateTime.diff(dt1, dt2)
18000
iex> DateTime.diff(dt2, dt1)
-18000

from_iso8601(string, calendar \ Calendar.ISO)

代码语言:javascript
复制
from_iso8601(String.t, Calendar.calendar) ::
  {:ok, t, Calendar.utc_offset} |
  {:error, atom}

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

由于ISO 8601不包括适当的时区,所以给定的字符串将转换为UTC,其偏移量将在几秒钟内作为此函数的一部分返回。因此,偏移量信息必须出现在字符串中。

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

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

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

实例

代码语言:javascript
复制
iex> {:ok, datetime, 0} = DateTime.from_iso8601("2015-01-23T23:50:07Z")
iex> datetime
#DateTime<2015-01-23 23:50:07Z>

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07.123+02:30")
iex> datetime
#DateTime<2015-01-23 21:20:07.123Z>

iex> {:ok, datetime, 9000} = DateTime.from_iso8601("2015-01-23T23:50:07,123+02:30")
iex> datetime
#DateTime<2015-01-23 21:20:07.123Z>

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

iex> DateTime.from_iso8601("2015-01-23T23:50:07.123-00:00")
{:error, :invalid_format}
iex> DateTime.from_iso8601("2015-01-23T23:50:07.123-00:60")
{:error, :invalid_format}

from_naive(naive_datetime, time_zone)

代码语言:javascript
复制
from_naive(NaiveDateTime.t, Calendar.time_zone) :: {:ok, t}

将给定转换NaiveDateTimeDateTime

它需要一个时区来放置NaiveDateTime。目前它只支持“Etc / UTC”作为时区。

实例

代码语言:javascript
复制
iex> {:ok, datetime} = DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
iex> datetime
#DateTime<2016-05-24 13:26:08.003Z>

from_naive!(naive_datetime, time_zone)

代码语言:javascript
复制
from_naive!(NaiveDateTime.t, Calendar.time_zone) :: t

将给定转换NaiveDateTimeDateTime

它希望有一个时区来放置NaiveDateTime。目前它只支持将“etc/UTC”作为时区。

实例

代码语言:javascript
复制
iex> DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC")
#DateTime<2016-05-24 13:26:08.003Z>

from_unix(integer, unit \ :second, calendar \ Calendar.ISO)

代码语言:javascript
复制
from_unix(integer, :native | System.time_unit, Calendar.calendar) ::
  {:ok, t} |
  {:error, atom}

将给定的Unix时间转换为DateTime

该整数可以按照不同的单位给出,System.convert_time_unit/3并在内部转换为微秒。

Unix时间总是使用UTC,因此DateTime将以UTC返回。

实例

代码语言:javascript
复制
iex> {:ok, datetime} = DateTime.from_unix(1464096368)
iex> datetime
#DateTime<2016-05-24 13:26:08Z>

iex> {:ok, datetime} = DateTime.from_unix(1432560368868569, :microsecond)
iex> datetime
#DateTime<2015-05-25 13:26:08.868569Z>

该单位也可以是一个整数,如下所示System.time_unit/0

代码语言:javascript
复制
iex> {:ok, datetime} = DateTime.from_unix(143256036886856, 1024)
iex> datetime
#DateTime<6403-03-17 07:05:22.320Z>

支持负Unix时间,最长-62167219200秒,相当于“0000-01-01T00:00:00Z”或0格里历秒。

from_unix!(integer, unit \ :second, calendar \ Calendar.ISO)

代码语言:javascript
复制
from_unix!(integer, :native | System.time_unit, Calendar.calendar) :: t

将给定的Unix时间转换为DateTime

整数可以根据以下不同的单位给出。System.convert_time_unit/3内部将转换为微秒。

Unix时间总是以UTC为单位,因此日期时间将在UTC中返回。

实例

代码语言:javascript
复制
# An easy way to get the Unix epoch is passing 0 to this function
iex> DateTime.from_unix!(0)
#DateTime<1970-01-01 00:00:00Z>

iex> DateTime.from_unix!(1464096368)
#DateTime<2016-05-24 13:26:08Z>

iex> DateTime.from_unix!(1432560368868569, :microsecond)
#DateTime<2015-05-25 13:26:08.868569Z>

to_date(date_time)

代码语言:javascript
复制
to_date(t) :: Date.t

DateTime转换成Date

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

实例

代码语言:javascript
复制
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> DateTime.to_date(dt)
~D[2000-02-29]

to_iso8601(datetime, format \ :extended)

代码语言:javascript
复制
to_iso8601(Calendar.datetime, :extended | :basic) :: String.t

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

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

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

警告:ISO 8601日期时间格式不包含时区或其缩写,这意味着在转换到这种格式时信息丢失。

实例

代码语言:javascript
复制
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> DateTime.to_iso8601(dt)
"2000-02-29T23:00:07+01:00"

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

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_iso8601(dt, :extended)
"2000-02-29T23:00:07-04:00"

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_iso8601(dt, :basic)
"20000229T230007-0400"

to_naive(date_time)

代码语言:javascript
复制
to_naive(t) :: NaiveDateTime.t

将给定datetime转换为NaiveDateTime

由于NaiveDateTime不保存时区信息,因此任何时区相关数据在转换过程中都将丢失。

实例

代码语言:javascript
复制
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 1},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_naive(dt)
~N[2000-02-29 23:00:07.0]

to_string(datetime)

代码语言:javascript
复制
to_string(Calendar.datetime) :: String.t

datetime根据日历将给定值转换为字符串。

实例

代码语言:javascript
复制
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> DateTime.to_string(dt)
"2000-02-29 23:00:07+01:00 CET Europe/Warsaw"

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

iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 0},
...>                utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
iex> DateTime.to_string(dt)
"2000-02-29 23:00:07-04:00 AMT America/Manaus"

to_time(date_time)

代码语言:javascript
复制
to_time(t) :: Time.t

DateTime转换为Time

由于Time没有保存日期或时区信息,转换过程中数据将丢失。

实例

代码语言:javascript
复制
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
...>                hour: 23, minute: 0, second: 7, microsecond: {0, 1},
...>                utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
iex> DateTime.to_time(dt)
~T[23:00:07.0]

to_unix(datetime, unit \ :second)

代码语言:javascript
复制
to_unix(Calendar.datetime, System.time_unit) :: integer

转换给定的datetime为统一时间干杯。

datetime预计将使用与上年大于或等于0的ISO日历。

据此,它将返回给定单位的整数System.convert_time_unit/3

实例

代码语言:javascript
复制
iex> 1464096368 |> DateTime.from_unix!() |> DateTime.to_unix()
1464096368

iex> dt = %DateTime{calendar: Calendar.ISO, day: 20, hour: 18, microsecond: {273806, 6},
...>                minute: 58, month: 11, second: 19, time_zone: "America/Montevideo",
...>                utc_offset: -10800, std_offset: 3600, year: 2014, zone_abbr: "UYST"}
iex> DateTime.to_unix(dt)
1416517099

iex> flamel = %DateTime{calendar: Calendar.ISO, day: 22, hour: 8, microsecond: {527771, 6},
...>                minute: 2, month: 3, second: 25, std_offset: 0, time_zone: "Etc/UTC",
...>                utc_offset: 0, year: 1418, zone_abbr: "UTC"}
iex> DateTime.to_unix(flamel)
-17412508655

utc_now(calendar \ Calendar.ISO)

代码语言:javascript
复制
utc_now(Calendar.calendar) :: t

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

实例

代码语言:javascript
复制
iex> datetime = DateTime.utc_now()
iex> datetime.time_zone
"Etc/UTC"

扫码关注腾讯云开发者

领取腾讯云代金券