我有一个具有以下架构的模型:
schema "my_things" do
(...)
field :shifted_inserted_at, :utc_datetime_usec
timestamps()
end
Run Code Online (Sandbox Code Playgroud)
timestamps()类型默认为:naive_datetime.
我需要改变我的inserted_at值并将其插入到shifted_inserted_at.
如何将 NaiveDatetime 转换为正确的格式?我尝试过这样的事情:
shifted_inserted_at =
my_thing.inserted_at
|> DateTime.from_naive!("Etc/UTC")
|> Timex.shift(days: 10)
my_thing
|> Ecto.Changeset.change(shifted_inserted_at: shifted_inserted_at)
|> Repo.update()
Run Code Online (Sandbox Code Playgroud)
但我得到:
** (ArgumentError) :utc_datetime_usec expects microsecond precision, got: #DateTime<2019-05-30 14:40:08Z>
Run Code Online (Sandbox Code Playgroud)
DateTimetype 有一个名为 的字段microsecond。它\xe2\x80\x99是一个表示值和精度的元组。
iex|1 \xe2\x96\xb6 DateTime.from_naive!(\n...|1 \xe2\x96\xb6 ~N[2016-05-24 13:26:08], "Etc/UTC").microsecond \n#\xe2\x87\x92\xc2\xa0{0, 0}\niex|2 \xe2\x96\xb6 DateTime.from_naive!(\n...|2 \xe2\x96\xb6 ~N[2016-05-24 13:26:08.123456], "Etc/UTC").microsecond\n#\xe2\x87\x92\xc2\xa0{123456, 6}\nRun Code Online (Sandbox Code Playgroud)\n\n正如人们所看到的,除非实际值确实有微秒,否则精度为零。
\n\n假设数据库中返回的值my_thing.inserted_at 具有微秒精度,可以简单地:
~N[2016-05-24 13:26:08.123456]\n|> DateTime.from_naive!("Etc/UTC")\n|> DateTime.add(10 * 24 * 60 * 60) # 10 \xc3\x97 seconds in a day\n#\xe2\x87\x92\xc2\xa0#DateTime<2016-06-03 13:26:08.123456Z>\nRun Code Online (Sandbox Code Playgroud)\n\n如果该值没有微秒精度,
\n\niex|3 \xe2\x96\xb6 DateTime.from_naive!(~N[2016-05-24 13:26:08], "Etc/UTC")\n# PRECISION \xe2\x87\x92 ZERO! \xe2\x87\x93\xe2\x87\x93\xe2\x87\x93 \n#\xe2\x87\x92\xc2\xa0#DateTime<2016-05-24 13:26:08Z>\nRun Code Online (Sandbox Code Playgroud)\n\n人们可能总是手动设置它:
\n\nwith dt <- DateTime.from_naive!(~N[2016-05-24 13:26:08], "Etc/UTC"),\n do: %DateTime{dt | microsecond: {elem(dt.microsecond, 0), 6}}\n#\xe2\x87\x92\xc2\xa0#DateTime<2016-05-24 13:26:08.000000Z>\nRun Code Online (Sandbox Code Playgroud)\n\n后者现在可能已插入数据库中。
\n我刚刚也看到了这篇文章,并找到了另一个对我有帮助的解决方案,所以我想我会分享。
如果您使用 Ecto,则可以使用Ecto.Type.cast/2如下所示:
with {:ok, naive_datetime} <- NaiveDateTime.utc_now(),
{:ok, datetime} <- DateTime.from_naive(naive_datetime, "Etc/UTC"),
{:ok, utc_datetime_usec) <- Ecto.Type.cast(:utc_datetime_usec, datetime),
do: utc_datetime_usec
Run Code Online (Sandbox Code Playgroud)
这是一个有点人为的示例,但您可以根据需要替换任何数据。它只是为了说明如何使用 Ecto 投射数据。
| 归档时间: |
|
| 查看次数: |
4889 次 |
| 最近记录: |