【问题标题】:Handling DateTime precision > 6 in Elixir在 Elixir 中处理 DateTime 精度 > 6
【发布时间】:2017-12-05 12:18:36
【问题描述】:

我的代码中有这个功能:

  defp to_date({year, month, day}), do: NaiveDateTime.from_erl!({{year, month, day}, {0, 0, 0}}, {0, 6}) |> NaiveDateTime.to_string()
  defp to_date({{year, month, day}, {hour, min, sec, msec}}) when msec < 1000000,
    do: NaiveDateTime.from_erl!({{year, month, day}, {hour, min, sec}}, {msec, 6}) |> NaiveDateTime.to_string()

  defp to_date(x), do: x

msec &gt; 6-digits时你会如何处理案件。

使用 Tds 库从 SQLServer datetime2(7) 提取数据可以正常工作:

iex(45)> r = Tds.Connection.query(:RMASDB, "select * from users where user_id = 1" , [])
{:ok,
 %Tds.Result{columns: ["user_id", "name", "email", "mobiles", "password", "roles", "active", "reset_required", "last_login", "has_picture", "last_modified", "last_modified_by"], command: nil, num_rows: 1,
  rows: [[1, "Charles Okwuagwu", "charleso@mydomain.com", "mobile1, mobile2", "/eNvuOyr5N6HxgYdz3fK7A==|QHx/sOa3Se0C3ZeLSNtT97SCsuWL11SJeLykms7faGY=", "Administrator", true, false,
    {{2017, 11, 30}, {18, 37, 26, 2690120}}, true, {{2017, 11, 30}, {0, 0, 0, 0}}, 1]]}}

但使用下面的代码处理日期会引发此异常:

iex(46)> DB.get(DB.Users, "select * from users where user_id = 1")                      
** (ArgumentError) cannot convert {{2017, 11, 30}, {18, 37, 26}} to naive datetime, reason: :invalid_time
    (elixir) lib/calendar/naive_datetime.ex:549: NaiveDateTime.from_erl!/2
    (rmas) lib/db.ex:34: DB.to_date/1
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
    (rmas) lib/db.ex:26: anonymous fn/3 in DB._objects/3
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2
    (rmas) lib/db.ex:17: DB.get/3

源数据值是:{{2017, 11, 30}, {18, 37, 26, 2690120}}

【问题讨论】:

  • 您的异常显示了一个包含 3 个元素的时间元组,而您的源数据值表示它是 4 个元素。哪个是正确的?
  • @JonasDellinger 源值是 4 个元素,它是一个 erlang 时间格式
  • Elixir 的错误报告出于某种原因仅显示 3 个元素
  • @JonasDellinger 我已经用完整的错误更新了问题
  • 为什么微秒还是超过 6 位数?看起来您正在使用的库中存在错误。你想用大于 1e6 微秒的时间做什么?将额外的添加到秒字段?

标签: datetime elixir precision


【解决方案1】:

datetime2(7) 字段以十分之一微秒的精度存储。 NaiveDateTime 仅支持微秒的精度,因此您可以将该值除以 10 以获得微秒并使用它:

defp to_date({{year, month, day}, {hour, min, sec, seven}}),
  do: NaiveDateTime.from_erl!({{year, month, day}, {hour, min, sec}}, {div(seven, 10), 6}) |> NaiveDateTime.to_string()

我们使用div而不是/进行除法,结果是整数而不是浮点数。

【讨论】:

  • 核心团队没有设计 NaiveDateTime.from_erl 的任何原因!处理超过{0..999999, 0..6}?考虑到VM支持:纳秒?
猜你喜欢
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 2014-08-07
  • 2014-01-19
  • 2018-03-13
  • 1970-01-01
相关资源
最近更新 更多