Best way to change a hour of a DateTime

I has a DateTime with a tz different of UTC and I need to update your hour, I used Map.put to this: Map.put dt, : hour, 5. Is there a best way to do this using DateTime or Timex

The DateTime struct is documented with its fields, therefore its totally fine to use Map.put/3 or even the update syntax (%{dt | hour: 5}).

Also, because of the public definition of the struct, its totally fine for you to access the fields directly and to change them. You probably won’t find functions that abstract this away.

3 Likes

Just be aware that this might result in an invalid datetime. Depending on the timezone there might be gaps or overlaps.

4 Likes

If your logic allows it, it might be worth looking at the add function of the DateTime module.

2 Likes

For my use case not allows, I need to put a specific hour in the datetime.

date = ~D[2005-04-05]
time = ~T[08:30:00]

with_timezone = date |> Date.to_erl |> Timex.DateTime.Helpers.construct("America/Sao_Paulo") 
with_timezone_and_time = Timex.add(with_timezone, Timex.Duration.from_time(time))

This isn’t as simple as using Map.put or the %{struct | field: val} syntax, but perhaps makes things more clear.

Another possibility still:

date = ~D[2005-04-05]
time = ~T[08:30:00]
{:ok, naive} = NaiveDateTime.new(date, time)
{:ok, with_timezone_and_time} = DateTime.from_naive(naive, "America/Sao_Paulo")
1 Like