jung-hunsoo

jung-hunsoo

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?

Showing Posts 1 to 10

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

mbuhot

mbuhot

The round trip via unix timestamp should be fine for UTC date times right?

idi527

idi527

If I understand you correctly, for round trip timing (as in rpc) it’s safer to use monotonic time. Otherwise you can get negative or skewed results if the underlying OS decides to change its time while the request is in-flight.

LostKobrakai

LostKobrakai

It’ll still not consider leap-seconds but that might be ok for your application.

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.

jung-hunsoo

jung-hunsoo OP

Thanks for the relies. I can understand and agree the various opinions.

I’m currently using Unix time for hours shift. And my ecto schema holds three fields; d_day_local :naive_datetime, d_day_utc :utc_datetime, time_zone :string. Calendar is in a dependencies to do this.

Dealing with time zone and DST is painful and fragile.

How do other languages deal with this problem? AFAIK, JS provides simple traveling methods. How about Erlang, Clojure, Go, and more?

I hope Elixir be more developer-friendly so that more dev guys gather. But sometimes I got confused which the Elixir is aimed at; Popular usage or Sophisticated purposes. Since Elixir is running on BEAM, popularity would be one of major goal. Am I right?

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).

Nicd

Nicd

Example from another language: Python doesn’t offer nearly any timezone handling capabilities out of the box. Usually you install pytz to deal with timezones. So in that regard, I don’t think of Elixir’s choice as odd in any way.

jung-hunsoo

jung-hunsoo OP

In js, Date instance can be easily traveled via .setHours() method.

I can now understand why now/3 is missing in DateTime module. Nevertheless we can think providing utc_time_travel method, which will be like a utc_offset.

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? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews