6/22/2026 at 9:59:52 PM
Future events: store the local (at the event) date and time and timezone. You’ll keep the right context even if lawmakers decide to switch things up. You want to see your doctor at 8:30 AM on Monday September 14, 2026 whether it’s daylight saving time, or standard time or “they” decide on a fractional hour offset between the time you set the appointment and the time you attend the appointment.Past events: UTC timestamp.
What format should you use? Human readable strings for longterm storage, because when things go wonky, it’s easier to debug.
Note: nothing stops you from optimizing for queries by adding a field to store (or using a calculated index for) the integer epoch offset (e.g. unix timestamps), just make sure you know which field is authoritative.
by jagged-chisel
6/23/2026 at 4:19:36 AM
Copying what I posted under the original[0] that no one noticed because it's quite relevant to your mention of UTC for past events:The naming of "timestamp with time zone" is one of my favorite pet peeves. It's one of those things that you can say "well technically it's true" about.
The article suggests that for past events, UTC and this timestamptz would be acceptable as a general rule, but even there it depends on what you will be doing with the data. If you intend to interpret it as a series of local occurrences and try to visualize/summarize that data later, you may be in for a surprise as your user has moved to another timezone and now all the past events are translated to the wrong local hours [1]. For example, your system might end up showing that the user's best time for jogging based on historical data is at 2 in the night.
by Ndymium
6/23/2026 at 4:22:52 PM
But if your user does jog from 2:00am to 3:30am, your localized data is going to look wrong in the fall in a timezone where the clock changes from daylight saving and the 2:00am hour repeats itself.It’s easier to convert historical records from UTC because the official rules don’t change for past dates (there may certainly be data errors in tzdata … what’re gonna do … )
by jagged-chisel
6/24/2026 at 5:30:14 AM
If my user does jog at 2 AM, then it's better to show 2 AM than 7 PM or 10 AM even if there is a slight chance that on one singular day 2 AM might repeat itself. The user who is aware of how daylight savings works will surely be able to figure that out.Technically you might argue that I should show 1 AM if the user did run at 2 AM in summer time, but everyone I personally know keeps their schedule over DST transitions. That is, if they did something at X o'clock before the transition, they'll keep doing it at X o'clock after it (sleep be damned). So generally showing 2 AM would be the most correct solution.
You cannot get that information from just UTC if you don't know where the user was when they made those historical events. Thus you either have to keep a history of their location (complicated) or just store the local timestamps (or at least the offsets) at the time of event. Always being able to convert from UTC with no extra data assumes that the user will never move, which might be fine if your application is limited to users in a single country.
by Ndymium
6/23/2026 at 3:11:24 AM
However, keep in mind that there is *no way* to store the time of a future event in a way that won't someday break unexpectedly. It just physically can't be done.Your approach assumes that we know what timezone the doctor's office will be in when the event happens. However, unless you know the exact lat/lon of that office — and maybe not even then — that's not something you can rely on.
Countries sometimes split themselves up. Provinces get annexed. Border towns may end up on the other side due to a treaty, even in times of peace. Multi-timezone countries may change which parts belong to which timezone. A town may get occupied, and the answer to the question of "what time is it" may depend on the loyalties of the person you ask.
Unless the doctor's office is physically located in Berlin, Germany, there is no guarantee that europe/berlin will always be its correct timezone. Even then, you may get the east/west Berlin split and one side deciding to abandon DST.
When an event happened in the past, we know exactly when it happened, and we can express that timestamp as "number of seconds after some reference point." When an event is planned for the future, we usually plan it for a specific hh:mm in a specific location, but we don't know when that is actually going to be.
by miki123211
6/23/2026 at 4:24:44 AM
Everything in the future is provisional and uncertain. The doctor could die, humanity could get obliterated, the database could go offline and you lose all your appointments.Should we all add precise GPS coordinates to our salon appointments in case that neighborhood is seized by commandos from Newfoundland who really really want us all on GMT? I’m personally not sure it’s worth the effort.
by eduction
6/24/2026 at 3:51:39 AM
"The doctor's office no longer exists" is the fault of whoever bombed the office, and not a bug in your software. "My phone shows me 3PM and they call me at 2PM to see where I am" is a bug in your software, at least according to the understanding of most users. "Oh you haven't taken the 2028 US second Civil War into account" is not a valid explanation.by miki123211
6/23/2026 at 6:51:20 AM
Funnily enough, Google Maps' Timeline tells me I went to a different restaurant 5 years ago. Imagine if you went to a McDonald's in 2019 and in 2021 it became a KFC. Google Maps today will say "You visited this KFC in 2019"!.by netsharc
6/23/2026 at 3:04:39 AM
Great advice! The really tricky part to me is when you have an event your recorded before it happened, but want to look it up after the event has passed (e.g., you want to look up the doctor's appointment a year after it occurred). The simplest and mostly solid answer I've been able to come up with is:1. If you want to know when something happened and a particular place is important (like the previously mentioned doctor's appointment), store the local date/time with timezone data. That covers you in case the timezone changes before your recorded event happens. Personally, I would not store reflexively store dates/times in a string. For the cases I encounter, that feels like primitive obsession since you can always use EXTRACT in a query to simplify output.
2. If will you need to lookup the date and time after an event occurred, write a separate field that includes timezone offset field (e.g. -1, +1, -8, etc.) in case you want to look up exactly when an event previously happened. This (mostly) covers you from timezone shifts that occur at that particular location between when you wrote the data vs some later date. This falls apart if the timezone you're converting to also changed their timezone between now and the event. Also, if your timezone shifts between when you wrote the record and the actual event.
I wonder if someone has a temporal record of timezone shifts. You could solve a lot of edge cases with something like that. Then you could write a query that asks for the timezone's offset as of a specific date. That would make life much easier. Then you could skip the timezone offset field I mentioned in #2.
by infamia
6/23/2026 at 9:41:13 PM
You have an appointment with the doc. That's just a placeholder for them to schedule employees for the day. You sign you when you arrive, UTC timestamp. They produce a record of your responses, UTC timestamp. Tests, UTC timestamps.Your appointment time is no longer the important item once it's in the past. It's probably easier to just get a list of your visits from the last year, and select the one you want to dig into. Not listed? Expand the range to 13 months. I doubt a situation exists where it matters that one must query the exact date and time in order to find that appointment.
by jagged-chisel
6/23/2026 at 6:15:09 PM
I'd say an event should have the date/time in local offset AND the location details rough or fine grained. OR the date/time should be stored/transmitted in UTC if it doesn't have a localized date+time+location.DateTime logic in general is just difficult in general.. Most systems can translate to/from UTC with ease, it's just when the localized offset of the futre changed like in this case.
by tracker1
6/22/2026 at 11:30:24 PM
What about virtual events between participants in different time zones? Whose do you keep stable if one has their clock moved under them?by lalaithion
6/23/2026 at 12:28:05 AM
If you're feeling nice, randomize whose time remains stable (to keep things fair), keep the organizer's time stable, or pick the time that minimizes the number of participants who will have the meeting time change.If you're feeling mean, randomize whose time remains stable (to make it hard to predict), move the meeting for the organizer, pick the time that maximizes the number of participants who will have the meeting time change, or split the difference and move everyone. Meeting was at 10 AM for Alice and 9 AM for Bob, but now it can be at either 11 AM for Alice and 9 AM for Bob or 10 AM for Alice and 8 AM for Bob? Now the meeting is at 10:30 AM for Alice and 8:30 AM for Bob.
by joshAg
6/23/2026 at 1:29:37 AM
This is the critical problem with all of this.Daylight savings time changes, can't be globally banned fast enough really.
by lucisferre
6/23/2026 at 2:22:56 AM
Every event should have an IANA timezone tied to a city like America/Vancouver or Europe/Berlin, and it should ideally be settable by the user. Some apps (e.g. Discord) don't expose this but have a time zone under the hood, and it's a huge pain every time daylight savings time comes along when an event's time zone is incorrectly in Europe instead of North Americaby subarctic
6/22/2026 at 11:15:56 PM
> What format should you use? Human readable strings for longterm storage, because when things go wonky, it’s easier to debug.You can just use a TIMESTAMP with no TZ data. It's functionally the same as using the string but simpler because you avoid all the string handling headaches and gain the benefit of avoiding to avoid double booking and date/time functions to answer questions like "how many appointments do I have in April?".
by mulmen
6/23/2026 at 1:02:18 AM
I am willing to concede to “human readable” and dropping “string” iff queries on TIMESTAMP are producing a human readable string (I believe they are … I haven’t been in postgres in at least six weeks and details like that don’t make a lasting impression in muh brain)by jagged-chisel
6/23/2026 at 4:43:04 AM
Why would queries on TIMESTAMP not produce human readable strings? Postgres has defaulted to a human readable mask for timestamp presentation for at least 25 years.See Current: https://www.postgresql.org/docs/current/datatype-datetime.ht...
And 7.1 (2001-04-13): https://www.postgresql.org/docs/7.1/datatype-datetime.html (Section 3.4.2)
by mulmen
6/23/2026 at 7:12:24 AM
Always store the location, too. Space-Time is a thing.by _glass
6/22/2026 at 10:13:01 PM
UTC for past events doesn't always work either. For example, historical employee punch-in times.UTC timestamps should only ever be used for points in time in the most literal sense, and nothing else.
by Xirdus
6/22/2026 at 10:35:12 PM
Why not? It sounds like it would be correct even if the employee has a shift that includes a offset change.Future timestamps should be local because local timezone changes literally change the instant the event it will happen (relative to UTC). For past things, this can’t happen
by drdexebtjl
6/22/2026 at 11:27:40 PM
Correct according to what? An employee who punched in at 9AM wouldn't show up as having punched in at 9AM anymore. Not unless you also store the exact timezone the UTC timestamps have been created with - but that's basically local timestamps with extra steps.by Xirdus
6/22/2026 at 11:40:27 PM
tzdata doesn’t change retroactively [1].If an employee clocks in at 2026-06-22 09:00 America/Sao_Paulo time, (which has a -03:00 offset today), and the server's clock is in UTC, the server will save 2026-06-22 12:00 to the database.
If America/Sao_Paulo changes to -02:00 on 2027, it doesn’t affect conversions for past dates. You still get 2026-06-22 09:00 when trying to convert 2026-06-22 12:00 to local time in America/Sao_Paulo.
edit: [1] unless it was wrong. in which case, you actually still want the UTC timestamp stored, so that you can just update tzdata and get correct local times, as opposed to saving the wrong local times in your database, that you now have to also fix.
by drdexebtjl
6/23/2026 at 1:49:55 AM
But which tzdata? Do you have the timezone or do you not have the timezone? If you have the timezone then why is your timestamp in UTC and not in the timezone that you have to store alongside the UTC timestamp?by Xirdus
6/23/2026 at 2:58:31 AM
Whichever timezone is relevant to the analysis later when the data is read.If you want to see if an employee is late compared to the time their shift starts, the system needs to know the time their shift starts in UTC, because otherwise if they start a shift in during a timezone change, it’ll think they’re extremely late/early.
If you want to pay them for their (clock out - clock in) time, UTC.
If they’re a remote worker on your team, and you want see your entire team’s availability, you should probably see it in _your_ local time instead.
I’ve found that whenever it looks like I need to know the local time that the user had when they did something, it’s because I’m implicitly anchoring it to some other timestamp that my system doesn’t know and that should also be recorded in UTC (like, in this example, the time their shift is supposed to start).
Some nuance applies, of course.
by drdexebtjl
6/23/2026 at 6:35:20 PM
Sometimes, the relevant timezone is whatever the local timezone was when and where the timestamp was recorded. Which is information that's lost on UTC conversion.Sure, you can reconstruct it if you stored the "where" part somewhere else, and associated the "where" with the timestamp's timezone (e.g. the Offices table has a Timezone column that you JOIN with the punch-in times). But that assumes you stored it somewhere else. It also assumes said storage is readily available. It also assumes there was no human error in recording that value (what if the office was accidentally assigned Seattle PST instead of BC PST back when it didn't matter?) It also assumes it was possible to record it correctly in the first place (what if the office is in Kimberley, BC but the software only allowed selecting BC timezone?)
Alternatively, you store the timezone directly in the timestamp itself and avoid all these problems and more.
by Xirdus
6/23/2026 at 7:07:47 PM
No tzdata. When a time becomes the past you canonicalize it to the UTC, or better yet TAI, second it occurred at. As in, this occurred N cesium atom vibrations after the zero timestamp.That is permanently fixed and can be losslessly and perfectly converted to the corresponding date in the past if you care about what local time was at that instant at some location.
by Veserv
6/22/2026 at 10:28:41 PM
If past timestamps (UTC or otherwise) are unreliable, then there is some kind of math-bug going on.by Terr_
6/22/2026 at 11:02:19 PM
Not always a math bug. Sometimes a human bug. Tzdata can have errors (it's crowdsourced after all) that cause past UTC stamps to be incorrect because that incorrect tzdata was used at conversion time. And since most people aren't storing the tzdata version they're using with the stamp, it would be very difficult to make corrections without also corrupting other stamps.The bottom line is, if wall time is important, past or present, wall time needs to be stored.
The only thing that can be guaranteed about a UTC timestamp is it's a UTC timestamp.
by dqv
6/22/2026 at 11:27:20 PM
When was the last time tzdata was wrong about a period that already passed?Most of my career I’ve seen problems where it’s out of date, never where it’s up to date and wrong.
by drdexebtjl
6/22/2026 at 11:33:44 PM
For the 2026a release: Changes to past and future timestamps
Since 2022 Moldova has observed EU transition times, that is, it has sprung forward at 03:00, not 02:00, and has fallen back at 04:00, not 03:00. (Thanks to Heitor David Pinto.)
by dqv
6/23/2026 at 12:14:32 AM
Interesting. I could see that as an argument also for storing it in UTC, no?For example, if tzdata is 1 hour off, and you store your timestamps in UTC, it's immediately obvious that a local time is wrong because users will see events that just happened as having happened 1 hour ago. Update tzdata, and now everything is right.
If you store the wall time, it _looks_ right, but fails if you attempt to compare/sort it with times in different timezones. To fix it, you need to actually modify the data in your database.
by drdexebtjl
6/23/2026 at 1:15:06 AM
Only for server-supplied timestamps.Like the time clock example: sure what you're describing works if the user is just pressing a button to clock in and the server stores a UTC timestamp in response to a POST request or whatever.
But it's very common to need to backfill time. So the user backfills with their own supplied timestamps, those stamps get converted to UTC, tzdata changes a few months later, and HR is now asking for an explanation as to why they were late for those backfills and how it's possible they were working an hour after the shop closed.
It's never as simple as "just store it in UTC".
Conversion to UTC is lossy, so I prefer to keep up with the user-supplied time where appropriate.
by dqv
6/22/2026 at 11:18:06 PM
Seems like for airtightness you'd store utc alongside utc of when timestamp was stored alongside timezoneby __s
6/22/2026 at 11:34:58 PM
"UTC or otherwise" is important. Are you storing otherwise, or are you storing UTC? There are times where storing otherwise will lead to data loss in case the law changes whereas storing UTC would work (when you care about a literal point in time, like access logs). And there are times where storing UTC will lead to data loss in case the law changes whereas storing otherwise would work (when you care about wall clock time, like punch-in times).by Xirdus
6/23/2026 at 1:46:56 AM
[flagged]by joejoegobot