【问题标题】:How to parse DateTime in Elixir?如何在 Elixir 中解析 DateTime?
【发布时间】:2017-04-19 03:18:59
【问题描述】:

如何从元组 {DD, MM, YY} 中创建 (Ecto.)DateTime,或者从 Elixir 中的字符串解析它?我应该使用 Erlang 的 DateTime 吗?

我在谷歌上搜索过,但没有找到任何东西,文档中也没有关于此事的任何内容,只有关于 DateTime 的一般信息——例如,如何获取当前日期和时间。

请注意,我不想使用第三方库,例如 Timex

【问题讨论】:

    标签: date datetime elixir


    【解决方案1】:

    要获取当前日期和/或时间,您可以使用其中之一

    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>
    

    您只需要确保您的数据按照这些函数所期望的正确顺序排列即可。

    至于从字符串中解析这些,你要么需要引入另一个库,要么自己编写一个解析器。

    【讨论】:

      【解决方案2】:

      只是添加贾斯汀给出的答案。 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中实现了。
      • 如何以字符串格式而不是 ~D[some-date] 打印日期?
      • Elixir 1.11 添加了一个Calendar.strftime/3 函数,它将满足大多数与日期时间相关的打印需求,但最简单的方法是将日期传递给Date.to_string/1。这将返回根据其日历格式化的日期,因此对于 Calendar.ISO 中的日期,这将是 yyyy-mm-dd。
      【解决方案3】:

      正如 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)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-28
        • 1970-01-01
        • 2019-08-26
        • 2020-07-16
        • 2023-03-04
        • 2016-03-02
        • 1970-01-01
        • 2010-12-07
        相关资源
        最近更新 更多