Why isn't there a DateTime.new?

I recently found myself having to refactor a piece of code that used Ecto.DateTime.from_date_and_time(date, time) and I was surprised that there wasn’t an equivalent function since the Ecto.DateTypes where removed.

I had a use case where I needed to create a new DateTime in order to use it in a datetime_add function. I eventually settled on two methods:

datetime = "#{Date.to_iso8601(date)}T#{Time.to_iso8601(time)}Z"
# "2019-03-06T23:59:59Z"
{:ok, datetime, _offset_from_utc} = DateTime.from_iso8601(datetime_iso8601)
# {:ok, #DateTime<2019-03-06 23:59:59Z>}


datetime = NaiveDateTime.new(date, time)
|> DateTime.from_naive("Etc/UTC")

and they both seem a little weird to me. In the first example I have to put the date and time into a string and the extrapolate on that. In the second example I have to go to a different place in the documentation which wasn’t that intuitive.

So how come there isn’t a DateTime.new()?

So how come there isn’t a DateTime.new()?

I think the answer is nobody proposed it. Feel free to do so!

I guess it’s shape could be:

@spec new(Calendar.date(), Calendar.time(), Calendar.time_zone()) :: {:ok, t()} | {:error, term()}

although, to follow NaiveDateTime.new/8 there should also be DateTime.new/12 (which is pretty wild)

I believe the reason is that Ecto.DateTime is more similar to NaiveDateTime: The decision was made to keep timezone-handling out of the Elixir core, which means that you have to use extra libraries like Timex to perform manipulation of dates and times.

DateTime itself is basically only in Elixir to ensure that we can use multiple of these external libraries alongside each-other, and that they accept the same datatype to work with.

A DateTime.new would not look like DateTime.new(date, time) but like DateTime.new(date, time, timezone_information).


  • I believe DateTime.new is not there so that people are forced to consider how they want to deal with timezones. In most cases, they either:
    • Work with a system that does not care about timezones and should be using NaiveDateTime instead
    • Care about timezones and should be using a library like Timex that handles them