mgwidmann

mgwidmann

My production (hobby) system started encountering errors tonight which look to be related to the time change. Heres the error:

** (ArgumentError) cannot convert ~N[2023-03-12 02:17:24] to datetime because such instant does not exist in time zone America/New_York as there is a gap between #DateTime<2023-03-12 01:59:59.999999-05:00 EST America/New_York> and #DateTime<2023-03-12 03:00:00-04:00 EDT America/New_York>
[info] (elixir 1.14.1) lib/calendar/datetime.ex:629: DateTime.from_naive!/3
[info] (flames 0.7.0) lib/flames_web/dashboard/helpers.ex:52: Flames.Dashboard.Helpers.display_timestamp/1
[info] (flames 0.7.0) lib/flames_web/dashboard/errors_live.ex:82: anonymous fn/4 in Flames.Dashboard.ErrorsLive.render/1
[info] (elixir 1.14.1) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
[info] (flames 0.7.0) lib/flames_web/dashboard/errors_live.ex:56: anonymous fn/2 in Flames.Dashboard.ErrorsLive.render/1
[info] (phoenix_live_view 0.18.16) lib/phoenix_live_view/diff.ex:398: Phoenix.LiveView.Diff.traverse/7
[info] (phoenix_live_view 0.18.16) lib/phoenix_live_view/diff.ex:139: Phoenix.LiveView.Diff.render/3
[info] (phoenix_live_view 0.18.16) lib/phoenix_live_view/static.ex:252: Phoenix.LiveView.Static.to_rendered_content_tag/4

The code which does this is located here:

https://github.com/mgwidmann/flames/blob/liveview/lib/flames_web/dashboard/helpers.ex#L52

In this case, it appears that the timezone cannot be converted because it lands in between the shift. Wouldn’t the appropriate action here, rather than a failure which occurs for an hour once a year (which is incredibly difficult to predict), be to just add 1 hour since it seems to already know that 2am goes to 3am and anything between 2am and 3am is actually just 3am+.

Why does the standard library put an exception that can happen so rarely like this? My system is down for the next 35 minutes I suspect until UTC time is past 3am.

Showing Posts 1 to 8

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

First, sorry for the production issues, that’s always unpleasant.

The thing is though, the standard library does not know that adding an hour is a valid interpretation of the data in the general case. It might be in your case, but you could just as easily be here on the forum reading a post by someone else about how the standard library silently advances inputs an hour during DST which leads to invalid duration logic (for example). Standard libraries should, in my opinion, err on the side of correctness, particularly in cases like date and time logic where there’s a lot of essential complexity.

As for how you would handle this, I would question where the datetime applied to display_timestamp comes from in the first place. Where are you getting the data for this instant in time given that, as Elixir notes, it does not exist?

mgwidmann

mgwidmann OP

I think the issue here was I was assuming the date is already in the timezone when it was actually UTC. It came from the database so I think thats the issue. I understand what you’re saying that it may not be correct in all cases. From the looks of things once I dug in, tzdata is at fault, not the standard library. It looks up to try to find this time and gets nothing back here:

https://github.com/lau/tzdata/blob/f9bdd778640586f692403530a3a687acb261db01/lib/tzdata/time_zone_database.ex#L46

I guess this is caused by my mistake to begin with since I was wrong about what the actual timezone was in this case but seeing as how these kinds of things happen very rarely its not likely something anyone will anticipate. Timezones are always hard. :disappointed:

trisolaran

trisolaran

Instead of assuming, a better approach is to read UTC timestamp from the DB into a DateTime struct, which carries the information that the time is in UTC. In this way you’re always dealing with a well-defined point in time that must exist in any time zone. Then you can call DateTime.shift_zone! with no fear.

Also note that if you call DateTime.from_naive instead of DateTime.from_naive! you will get an appropriate result even when dealing with times that are ambiguous in the given time zone, so you can react to it.

But the UTC-based approach is the easiest solution IMO.

dfalling

dfalling

I’ve gone through four iterations of storing dates, times, and timezones in my DB and finally learned about “wall time” from this great discussion. Strongly recommend reading through that and seeing if like me it would make more sense for you to store your dates as naive with a separate timezone field.

trisolaran

trisolaran

Wall time is kind of a special case though. If you’re only interested in storing a specific point in time (such as the timestamp from a past event) as opposed to “4pm in New York on a certain future date”, then you don’t need to store the time zone.

Taking a look at the OP example, it seems to me that his application is storing timestamps.

dfalling

dfalling

Yeah, I think you’re right. I thought because of their code dealing with the timezone that they cared specifically about it but I think I just misread it.

al2o3cr

al2o3cr

Nitpick: none of the functions used in the code above do any “converting” - you won’t find a single + or - anywhere. All they do is add and remove the timezone information to change the shape of data between NaiveDateTime and DateTime.

mgwidmann

mgwidmann OP

Blockquote

So it is actually storing it using Ecto as a :utc_datetime. But in an effort to support other cases, you can see above on line 42 of the code linked in the original post, it calls display_timestamp again. It seems this was the problem. 2:30 AM in UTC time on that day, dropping timezone info, followed by converting to a DateTime using timezone info from configuration rather than doing a shift in timezone directly from UTC. As @al2o3cr points out, nothing is added or removed:

I realize now this method is also probably the wrong time and not correctly adjusted for the configured timezone. Since this is an error dashboard used only by myself I never really verified the timestamps were off by a few hours since everything that occurs usually happens in the past. Heres what the dashboard looks like for those who are curious:

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews