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)

Last Post!

OvermindDL1

OvermindDL1

Which will be incorrect if some leap-time happens between then and now, thus this method is incorrect unless you are indeed wanting an absolute time instead of a relative one.

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
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
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
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
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New

Other popular topics Top

hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement