mudasobwa

mudasobwa

Creator of Cure

Adding days with a TZ is confusing

This question is more about semantics. Adding a :day to the DateTime instance changes the time value, which might be slightly confusing.

iex(1)> DateTime.new!(~D[2024-04-06], ~T[23:59:00], "Australia/Sydney")
...(1)>   |> IO.inspect()
...(1)>   |> DateTime.add(1, :day)
#DateTime<2024-04-06 23:59:00+11:00 AEDT Australia/Sydney>
#DateTime<2024-04-07 22:59:00+10:00 AEST Australia/Sydney>

Yes, adding the exact number of seconds (86_400) multiplied by the number of days results in this, but DateTime(dt, 5, :day) usually means the developer wants to get the very same hh:mm:ss time back.

Consider a ToDoApp (huh) example. If I am after producing a Stream of recurring events, I am surely to expect it won’t change the Time part alongside with a DST change.

I discovered this when people complained about Tempus.Slots.Stream.recurrent/3 is broken in an aforementioned way. I fixed it by reassuring Time part to stay intact in the produced stream elements, but it looks like a hack and I am positive, DateTime.add(…, …, :day) should not corrupt the Time anyway.

Thought?

Most Liked

LostKobrakai

LostKobrakai

This function relies on a contiguous representation of time, ignoring the wall time and timezone changes. For example, if you add one day when there are summer time/daylight saving time changes, it will also change the time forward or backward by one hour, so the elapsed time is precisely 24 hours.

This is called out in the docs as the intended behaviour.

If you want a continuous stream of datetimes at the same hour you can use a date and Date.add and turn those dates into datetimes with a time. Though you might run into invalid/duplicate datetimes this way if a date+time combination is in a DST change switch.

zachallaun

zachallaun

The docs for the new DateTime.shift/3 landing in 1.17 addresses this specifically and offers a suggestion using NaiveDateTime. It looks like this works:

iex(1)> Mix.install([:tz])
:ok
iex(2)> Calendar.put_time_zone_database(Tz.TimeZoneDatabase)
:ok
iex(3)> dt = DateTime.new!(~D[2024-04-06], ~T[23:59:00], "Australia/Sydney")
#DateTime<2024-04-06 23:59:00+11:00 AEDT Australia/Sydney>
iex(4)> dt |> DateTime.to_naive() |> NaiveDateTime.add(1, :day) |> DateTime.from_naive(dt.time_zone)
{:ok, #DateTime<2024-04-07 23:59:00+10:00 AEST Australia/Sydney>}

Edit to note that the above isn’t using anything in 1.17 and was copied from a 1.16 REPL.

LostKobrakai

LostKobrakai

DateTime.shift could make that decision, sure. But DateTime.add adds a certain (and fixed per amount/unit) amount of seconds to the supplied DateTime. That’s a different task. The issue is that it allows for :day with a constant of 86400 seconds when days are not always that long. That’s also the reason why :week, :month, :year weren’t added to DateTime.add, but handled into the new DateTime.shift.

Where Next?

Popular in Discussions Top

jeramyRR
This is an interesting article to read. Elixir’s performance, like usual, is excellent. However, it seems like the high CPU usage is co...
New
Qqwy
Looking at the stacks that existing large companies have used, WhatsApp internally uses Mnesia to store the messages, while Discord uses ...
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New
AstonJ
If a newbie asked you about Phoenix Contexts, how would you explain the basics to them? Feel free to be as concise or in-depth as you li...
New
restack_oslo
Hello, Please pardon me for any faux paux. I am 46 and this is my first time on a forum of any kind. I wanted to to get answers from tho...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement