jung-hunsoo

jung-hunsoo

DateTime.add/3 is missing

In Elixir, function DateTime.add/3 is missing.

There are Date.add/2, NaiveDateTime.add/3, and Time.add/3. But only DateTime has no add/3 function. Is there any reason? Maybe because of time zone related problem?

As as walkaround, I’ve convert it to Unix time |> shift time, then compare with another.

I think DateTime.add/3 can be achieved by using both DateTime.from_unix/3 and DateTime.to_unix/2. Is there any enhancement for this function?

Marked As Solved

LostKobrakai

LostKobrakai

It’s not about popular or sophisticated, but rather about correctness vs. full of edge-case issues. Elixir does only supply the functionality, where it can ensure correctness. That’s why NaiveDateTime does have more functionality than DateTime. Also NaiveDateTime clearly communicates that it’s a simple form of handling dates, which might be enough for some usecases. But doing DateTimes correctly is not simple as @Qqwy explained above.

As for your question about other languages. Afaik erlang does not supply any datetime calculations at all. JS (Date obj) doesn’t have any add/sub methods as well. Just a lot of setters/getters. For languages, which allow transformation of dates you might want to check how well they work before trying to compare it to elixir not giving you a way to do it correctly as well as incorrectly (for DateTime; NaiveDateTime would be the explicitly incorrect way).

Also Liked

Qqwy

Qqwy

TypeCheck Core Team

@LostKobrakai is completely right.

What do you require the timestamps for?
There are two reasons why the calendar- and timezone-related stuff is not part of the Elixir standard library:

  1. it greatly increases the size of the stdlib, which is a problem in embedded contexts.
  2. Time zone information frequently changes, regardless of stdlib-versions or what the latest compilation-moment has been. Extra libraries like tzdata periodically fetch timezone information from a repository at runtime to ensure that even if a server runs for a long time, its timezone-information remains correct.

It is a common misconception that Unix/POSIX-time is compatible with UTC time, but this is not completely true: POSIX time predates our UTC standard, and counts seconds since 1970-01-01T00:00 , but it will (for backwards compatibility) still pretend that:

  • every day only contains 86400 seconds
  • every year only contains 31536000 seconds (normal year) or 31622400 (leap year).

Many old libraries check if it is one second past midnight by doing time % 86400 == 1. Obviously this horrendously breaks if we would have leap seconds in there. (The alternative, which would be to create and use better algorithms, is impossible with software that is already in use for many years)

So… that is where we stand. Only during leap seconds, POSIX deviates from UTC. The real standard says that once the leap second is over, the POSIX clock should be decremented by one second, although there are other implementations that instead slow down the time ticks on the ‘leap second day’ to ensure time keeps flowing monotonically.

Maybe this is too much of a tangent, but the tl;dr is: DateTime.add does not exist because it is not possible to define it without a lot more information.

LostKobrakai

LostKobrakai

That’s the misconception here. That does not work at all because unix timestamps don’t deal with timezones (e.g. switch from/to daylight-savings-time), it does also not include leapseconds, which DateTime does need to deal with. That’s where elixir currently depends on third party libraries like timex or calendar. Even the database with timezone information (tzdata library) is by now third party.

You might want to read up on some of the articles like this one if you want to know more about the uncomfortable details in handling dates: Falsehoods programmers believe about time: @noahsussman: Infinite Undo

LostKobrakai

LostKobrakai

Changing to fixed values is still vastly different to adding/substracting time from dates. One does only need to validate a datetime on it’s own, while the other does need to make sure the time difference is calculated correctly to the resulting datetime. The latter is certainly more prone to issues like leap-seconds and such things.

But even for just changing parts of a datetime there’re things to consider: e.g. on switch between dst/non-dst you loose one hour once a year. Most often time is moved from 2:00 to 3:00 directly so setting a time 2:15 for that date will result in an invalid datetime. And with the needed knowledge of timezones we’re back to the problems discussed before.

To cite mdn for the javascript Date object here:

Creates a JavaScript Date instance that represents a single moment in time. Date objects are based on a time value that is the number of milliseconds since 1 January 1970 UTC.

So a date object is basically just a big integer value in UTC and therefore prone to all the issues mentioned above. It seems the only support in regards to timezones it has is using the host systems data to convert the UTC time into the timezone of the host. This is no better then using NaiveDateTime in elixir.

Edit:
And to clear out the notion that utc offsets might be all you need: How to save datetimes for future events - (when UTC is not the right answer)

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
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
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

We're in Beta

About us Mission Statement