问题
In my Phoenix app, I'm trying to insert an event record into the database that has fields for start_time
and end_time
- the datetime data will already be converted to ISO string format on the client and passed to the Phoenix API as JSON data, but this is causing me some trouble when I try to make an insert - the model is expecting those values to be :utc_datetime
so I need to convert them - I read through the documentation, but I'm still not sure...
First off, here's the schema for the model:
@primary_key {:id, :string, []}
@derive {Phoenix.Param, key: :id}
schema "calendar_event" do
field :start_time, :utc_datetime
field :end_time, :utc_datetime
field :description, :string
timestamps()
end
JSON data from the client would look like:
{
"start_time": "2017-09-28T18:31:32.223Z",
"end_time": "2017-09-28T19:31:32.223Z",
"description": "Test insert"
}
And if I were to (incorrectly) try to insert this data as-is, the statement would look like:
MyApp.Repo.insert(%MyApp.CalendarEvent{id: "calendar_event:test1", start_time:
"2017-09-28T18:31:32.223Z", end_time: "2017-09-28T19:31:32.223Z",
description: "Test insert"})
As expected, this throws an error that my datetime data does not match type :utc_datetime
. Ok, that's cool, but my question is, with the data already in ISO string, how can I convert it to that Elixir/Ecto recognizes it as valid :utc_datetime
?
回答1:
You want a DateTime
struct for your :utc_datetime
field, as you can see in the docs here: https://hexdocs.pm/ecto/Ecto.Schema.html#module-primitive-types
You can get a DateTime
from an iso string like the one you had above like this:
iex> {:ok, dt, 0} = DateTime.from_iso8601("2017-09-28T18:31:32.223Z")
iex> dt
#DateTime<2017-09-28 18:31:32.223Z>
(The zero in the tuple is the UTC offset)
Note: Support for Elixir Calendar types was introduced in Ecto 2.1. DateTime.from_iso8601/1
was introduced in Elixir 1.4.
来源:https://stackoverflow.com/questions/46477117/phoenix-ecto-converting-iso-string-into-utc-datetime-primitive-type