2

I know JavaScript, but I'm very new to Elixir and Phoenix. How do I get a javascript object from the frontend converted to something Ecto can convert to a DateTime value for the db?

Also, will it preserve the timezone? Or how should I deal with those?

  • For the first part, `date.toISOString()` on the client, and `DateTime.from_iso8601("...")` on the server. I don't think a native JS Date has a timezone, see http://stackoverflow.com/questions/15141762/how-to-initialize-javascript-date-to-a-particular-timezone. – Dogbert May 18 '17 at 20:56
  • `new Date()` in the console just gave me `Thu May 18 2017 22:57:31 GMT+0200 (CEST)` so it's there. I managed to get as far as `toISOString()` also, and it just puts in the db no prob. I'll see if the `from_ios8601` will make a difference. :) –  May 18 '17 at 21:00
  • It doesn't of course; since `date.toISOString()` throws the tz away. –  May 18 '17 at 21:03
  • You're right. http://stackoverflow.com/questions/17415579/how-to-iso-8601-format-a-date-with-timezone-offset-in-javascript will give you an ISO String with Timezone, but it looks like `DateTime.from_iso8601` doesn't parse timezone values. The timex package should have a function to do this. – Dogbert May 18 '17 at 21:11

1 Answers1

2

You can use iso8601 datetime strings between your javascript and elixir backend.

The simplest way to convert this to an Ecto schema is to declare the field as utc_datetime

You can then use Ecto.Changeset.cast to automatically convert the string to a %DateTime{} struct.

defmodule Blog do
  use Ecto.Schema
  schema "blog" do
    field :publish_at, :utc_datetime
  end

  def new(params) do
    %Blog{} 
    |> Ecto.Changeset.cast(params, [:publish_at]) 
    |> Ecto.Changeset.apply_changes()
  end
end

iex> Blog.new(%{"publish_at" => "2017-01-01T12:23:34Z"})
%Blog{__meta__: #Ecto.Schema.Metadata<:built, "blog">, id: nil, publish_at: %DateTime{calendar: Calendar.ISO, day: 1, hour: 12, microsecond: {0, 0}, minute: 23, month: 1, second: 34, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0, year: 2017, zone_abbr: "UTC"}}

Note: Any timezone offset will be discarded using this approach.

Mike Buhot
  • 4,790
  • 20
  • 31
  • Would you then add another field to the model describing what timezone it was created in? –  May 18 '17 at 21:07
  • To preserve timezone, I'd go with Timex.Ecto: https://hexdocs.pm/timex_ecto/Timex.Ecto.DateTimeWithTimezone.html#content – Mike Buhot May 18 '17 at 21:12