Search code examples
datetimeelixirphoenix-frameworkecto

Converting between Ecto.DateTime and DateTime


I have one date-time in Ecto.DateTime and the 2nd one in DateTime. How can I convert them to each other? Isn't there a easy way without external dependencies? There's nothing in the documentation. One of them has to_erl, another from_unix, but there's no overlap in methods, such as to_unix/from_unix or to_erl/from_erl or something similar.


Solution

  • The equivalent of Ecto.DateTime is NaiveDateTime, since neither of them store a timezone, while DateTime does. Erlang datetimes also do not have a timezone, which is why there's no to_erl and from_erl in DateTime.

    You can first convert to NaiveDateTime and then use DateTime.from_naive/2 along with the timezone your datetime is in (Elixir only supports Etc/UTC as of Elixir 1.4):

    iex(1)> Ecto.DateTime.utc |> Ecto.DateTime.to_erl |> NaiveDateTime.from_erl! |> DateTime.from_naive!("Etc/UTC")
    %DateTime{calendar: Calendar.ISO, day: 8, hour: 4, microsecond: {0, 0},
     minute: 49, month: 2, second: 9, std_offset: 0, time_zone: "Etc/UTC",
     utc_offset: 0, year: 2017, zone_abbr: "UTC"}
    iex(2)> DateTime.utc_now |> DateTime.to_naive |> NaiveDateTime.to_erl |> Ecto.DateTime.from_erl
    #Ecto.DateTime<2017-02-08 04:50:23>
    

    If you were using Ecto.DateTime earlier though, you probably want to use NaiveDateTime now.