【发布时间】:2017-04-19 03:18:59
【问题描述】:
如何从元组 {DD, MM, YY} 中创建 (Ecto.)DateTime,或者从 Elixir 中的字符串解析它?我应该使用 Erlang 的 DateTime 吗?
我在谷歌上搜索过,但没有找到任何东西,文档中也没有关于此事的任何内容,只有关于 DateTime 的一般信息——例如,如何获取当前日期和时间。
请注意,我不想使用第三方库,例如 Timex。
【问题讨论】:
如何从元组 {DD, MM, YY} 中创建 (Ecto.)DateTime,或者从 Elixir 中的字符串解析它?我应该使用 Erlang 的 DateTime 吗?
我在谷歌上搜索过,但没有找到任何东西,文档中也没有关于此事的任何内容,只有关于 DateTime 的一般信息——例如,如何获取当前日期和时间。
请注意,我不想使用第三方库,例如 Timex。
【问题讨论】:
要获取当前日期和/或时间,您可以使用其中之一
Ecto.Date.utc
Ecto.Time.utc
Ecto.DateTime.utc
DateTime.utc_now
至于将{DD, MM, YY} 元组转换为Ecto.Date,您将无法使用ecto 提供的函数来实现。但是,您可以使用 {YYYY, MM, DD} 元组转换为 Ecto.Date。
Ecto.Date.from_erl({2016, 12, 4})
#Ecto.Date<2016-12-04>
Date.from_erl({2016, 12, 4})
{:ok, ~D[2016-12-04]}
Ecto.Time.from_erl({13, 55, 10})
#Ecto.Time<12:10:08>
Ecto.Time.from_erl({13, 55, 10})
{:ok, ~T[13:55:10]}
Ecto.DateTime.from_erl({{2016, 12, 4}, {13, 55, 10}})
#Ecto.DateTime<2016-12-04 13:55:10>
Ecto.Date.from_erl({2016, 12, 4}) |> Ecto.DateTime.from_date()
#Ecto.Date<2016-12-04>
您只需要确保您的数据按照这些函数所期望的正确顺序排列即可。
至于从字符串中解析这些,你要么需要引入另一个库,要么自己编写一个解析器。
【讨论】:
只是添加贾斯汀给出的答案。 Elixir 的标准库可以解析 ISO 8601 日期。
iex> Date.from_iso8601("2015-01-23")
{:ok, ~D[2015-01-23]}
或使用 bang 版本,这可能会引发错误:
iex> Date.from_iso8601!("2015-01-23")
~D[2015-01-23]
如果您想要来自 ISO 8601 字符串的完整日期时间,您必须对 NaiveDateTime 感到满意,因为没有可靠的时区信息可供继续。
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07")
{:ok, ~N[2015-01-23 23:50:07]}
请注意,它只会丢弃时区偏移量。
将来会有一个from_iso8601/1 在 DateTime 上,但它是最近添加的,并且从 Elixir v1.3.4 开始还没有发布。它将保留时区偏移量,但将时区设置为 UTC。
【讨论】:
from_iso8601/1已经在Elixir v1.5.1中实现了。
正如 Martin Svalin 和 Erik Vullings 已在此处评论的那样,您现在可以在纯 Elixir 中将字符串解析为 DateTime:
iex(5)> {:ok, date_time, offset} = DateTime.from_iso8601("2018-03-17 21:23:12+0100")
{:ok, #DateTime<2018-03-17 20:23:12Z>, 3600}
如您所见,我在字符串中设置了 +1 小时的偏移量。它已正确解析,但 DateTime 对象不保留时区信息,当我打印它时,它会显示正确的日期和时间,但默认以 UTC 打印。
如果您想保留原始时区信息,则将其存储为元组第三个元素中的偏移量(以秒为单位)(在上面的示例中为offset)。
【讨论】: