Elixir 零时时间为 24

Elixir zero hour time as 24

我需要在 elixir 中将 erlang 时间戳转换为 NaiveDateTime。

  NaiveDateTime.from_erl {{2019, 4, 24}, {24, 0, 0}}
  {:error, :invalid_time}

NaiveDateTime(以及 elixir 中的所有其他时间模块)的文档不支持 24 作为零时间,即使它与 ISO8601 兼容。

关于如何处理这个问题有什么想法吗?我可以在元组上进行模式匹配,然后将其更改为 0,但我觉得这是一个非常丑陋的解决方案。有什么想法吗?

谢谢

更新 我的解决方案:感谢@Aleksei Matiushkin 的调整。

defmodule Helpers do
    def naive_date_time({{y, m, d}, {24, 0, 0}}) do    
       case NaiveDateTime.from_erl({{y, m, d}, {0, 0, 0}}) do
           {:ok, naive_dt} -> {:ok, NaiveDateTime.add(naive_dt, 24 * 3_600)}
           {:error, reason} -> {:error, reason}
       end
    end
    def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)
  end

文档明确指出 this format is not supported:

while ISO 8601 allows datetimes to specify 24:00:00 as the zero hour of the next day, this notation is not supported by Elixir

也就是说,即使在将来也不应期望处理此问题。我会使用显式辅助函数:

defmodule Helpers do
  def naive_date_time({{y, m, d}, {24, 0, 0}}),
    do: NaiveDateTime.add({{y, m, d}, {0, 0, 0}}, 24 * 3_600)
  def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)
end

我看不出这里有什么丑陋之处。请注意,转换 {24, 0, 0}{0, 0, 0}.

时,应该 增加 一天

注意! 上述解决方案针对格式错误的输入提出。请参阅原始问题中的更新或以下内容进行修复:

defmodule Helpers do
  def naive_date_time({{y, m, d}, {24, 0, 0}}) do    
    {{y, m, d}, {0, 0, 0}}
    |> NaiveDateTime.from_erl()
    |> naive_date_time_add()
  end
  def naive_date_time(dt), do: NaiveDateTime.from_erl(dt)

  defp naive_date_time_add({:ok, dt}),
    do: {:ok, NaiveDateTime.add(dt, 24 * 3_600)}
  defp naive_date_time_add(err), do: err
end