Hacker News new | ask | show | jobs
by gwbas1c 910 days ago
> The amount of DST-related bugs that I've fixed over the years amazes me

> yet ignores DST

Uhm, you do know that you're supposed to use a neutral timezone (Such as UTC) internally in your code / schema, and convert to local time in the UI?

The bugs that I've hit generally have to do with using local time accidentally when UTC is expected.

> because every single developer has moved clocks back and forth twice a year for their entire lives

WTF? Every single developer knows that their database schema should be in UTC and thus immune to DST issues.

2 comments

It sounds like you’re ignoring the fact that sometimes programs want to do things based on the user’s current time, and there _are_ reasons for developers to need to be aware of DST and handle edge cases correctly.

I inherited some code that was sending push notifications to users with a daily summary. I don’t remember why it was tripping over DST, since the notifications were at a “reasonable” hour (9am?) and afaik the time change happens during the hours most people are asleep, but the ruby API being used had errors for “there are zero / two times that match the time you asked for”.

I had to scratch my head for a little on why we were seeing both the zero and two errors in September / October, despite being intellectually well aware that the southern hemisphere seasons are the opposite of the northern.

But using UTC solves that problem, no? The time only changes in DST but not in UTC. If the code checks the time against UST, it will never trip up.

Anyways, the only real solution for managing time is to use a library like Luxon so you can stop thinking about it. Time is like cryptographic encryption - Don't roll your own solution if there is a battle tested library available.

It does not. I've got a specification that all inputs and outputs are in local time. Sometimes the timezone isn't known yet. Or at all.
Well, when it's not time, just some numbers. The most you can do is to store as is, hoping to figure out what that means later.

Also, even if all inputs and outputs are in local time, it still makes sense to process everything in UTC. There are a lot of weird corner cases making math on datetime really complicated

This doesn't work reliably for future timestamps. If a user submits a local timestamp and you then convert it to UTC, you're using the current definition of what we think that offset will be at that future time.

However, timezone definitions change. By doing the conversion, you've got to remember to check that the offset between what you stored and the user's local hasn't changed since the time you did the conversion. How often and when you do this checking is ... not obvious.

UTC or unix timestamp gets you moment of time. You know exactly moment event happened. Definitions can change, but usually not retroactively. TZdata is a database of such changes, and stores definition changes, basically all *nix OSes depend on it to cast moment of time into timezone. You can always convert timestamp in the past into desired timezone. If you work with calendars and want you know what "04:00 tomorrow" means - good luck, you'll need it. as example, "04:00 tomorrow" may not exist at all
I worked in a system a long time ago where someone came up with the bright idea of running batch jobs in such a way that the job would complete by the time we were in the users timezone morning hours. You know, so they could get the data when they were awake.

As time went on, the jobs started taking longer and longer and eventually took longer than the whole local morning, which resulted in them being awake AND being able to complain about it. The other issue was DST... users who were used to waking up and getting their data right away... would either be delayed an hour, or be done an hour early. Sometimes, the jobs would also run 2x or not run at all.

It was an utter mess of unintended consequences.

It was checking for something like “is it 9am in PST / PDT right now? What about EST / EDT?”

Or maybe, “what’s the current time in this list of time zones and then I’ll send notifications to users where it’s 9am”

Or something, I don’t specifically remember. The point is that notifications aren’t generated until they’re supposed to be sent, and we didn’t want that to vary by 1 hour with daylight savings.

And this specific use case aside, I think it’s true that there’s a class of use cases where developers do need to consider DST.

I have no doubt that this may have been some crazy complicated case (as dealing with time can be) but I can't help the armchair quarterback debugging. Could this not have been addressed by periodically running a script that generated when (in UTC) a notification should be sent and then another script to send the notifications when that time comes around ie

Script 1: send notification to User 123 at 9:00 UTC

Script 2: It is 9:00 UTC, which users are due to have notifications that have not been sent?

This way, the timezones don't ever really come into play. The axiom I follow for dealing with time is collect and display time in user's local time but store and process in UTC.

If you choose to divide it like that, script 1 is the one that needs to know about DST, because user 123 might be 9 UTC today, but what is it tomorrow?

Might change due to a DST change (which varies by time zone, and time zone DST date can change year-to-year), or the user might change time zones. Either way, your Script 1 is the logic that had the bug I inherited.

As soon as a time refers to "a time in a specific location" you need to store the location or timezone and can't just rely on UTC. There's a bunch of ways to do that, but "store as UTC, convert to local time in UI" is very simplistic that doesn't always work.

For things like, say, HN posts or whatnot storing as UTC is usually the right answer, but even here there's some nuance; for example email Date: headers tend to include the TZ of the person who sent them, and if you just store all of that as UTC you lose that information.