What if you're storing a calendar date, such as a birthday? A timestamp is inappropriate, and it's meaningless to discuss timezones in this context.
(Example - you want to know if a person is old enough to buy cigarettes, and you need to store a birthday that you can compare against the current day to see if they're legally 18 - if you store an epoch at UTC, do you store the time of day they were born? That's not the way the law works. Do you store midnight UTC? If they're currently in NY, can they but cigarettes at 7pm the day before their birthday because they're currently 18 in London?)
Sometimes you need a logical calendar date, not a point in time in the history of the universe.
That’s a great question. ISO 8601 doesn’t allow timezone offsets on date-only strings.
If you were born in the US, can you buy cigarettes at 12:00 am on your 18th birthday in London?
I’ve never heard of age verification laws caring what timezone you were born in. In fact, you couldn’t even pinpoint this from many people’s ID cards. Plenty of US states span multiple time zones, and I wouldn’t be that surprised if there were a maternity ward out there sitting on a TZ line.
The answer is that no age related verification-problem in real world is so sensitive that a day plus or minus would make any difference. So they skip the entire clusterfuck of a problem of timezones by just ignoring them.
I grew up in a country where you could legally buy beer with 16 and and hard alcohol with 18. So if the answer to "when should someone be allowed to choose to drink alcohol" has a variance of multiple years between countries who cares about a day or two.
It’s 2025 and major backend stacks have domain-specific time types like LocalDate etc. Using them is the only correct and actually the simplest solution.
If you want to store a date you don't need to store a time, time zone, etc. and your question goes away.
Certainly if you want to store birth dates and do age verification there is no point bothering with these issues, just store calendar date. Trivial to get date for age limit purposes.
ISO 8601 allows for 2 or 6 digit years. Truncating to 2 is just incorrect, and 6 digits is absurd. And you can read the RFC without paying ISO - and you can discuss the RFC with people who have also read it instead of relying on people using the Wikipedia page to interpret and explain ISO 8601.
I have a scheduling service at work and I keep getting requests for implementing ISO 8601 timestamps but I ignore them. RFC3339 is the way forward.
Not that I’ve ever really had cause to use it in anger, but I like the idea of ISO week dates.
Effectively, the ISO weak year (often differs from the calendar year in the last week of December / first week of January), ISO week number and day of week form a leap week calendar - instead of having 365 days in a common year and 366 in a leap year, it has 364 days in a common year and 371 in a leap week year, with leap weeks (obviously) being less frequent than leap days.
The Sym454 calendar [0] takes this idea further to create a perpetual calendar, with 12 months of 4 or 5 weeks; in leap years the 12th month is 5 weeks instead of 4 weeks long. However, the leap week rule proposed by Sym454 is different from that proposed by ISO 8601; the author of Sym454 argues his proposed rule has theoretical advantages (simple calculation and more uniform distribution of leap weeks). That said, there is a variant of Sym454 which uses the ISO 8601 leap week rule.
I believe two-digit years haven't been allowed for a while:
> ISO 8601:2000 allowed truncation (by agreement), where leading components of a date or time are omitted. Notably, this allowed two-digit years to be used as well as the ambiguous formats YY-MM-DD and YYMMDD. This provision was removed in ISO 8601:2004.
The problem is that can be difficult to portably determine. One wishes POSIX had an API “give me IANA time zone name for current process” which would do the needful to work it out (read TZ environment variable, readlink /etc/localtime, whatever else might be necessary)… but no, you are left to do those steps yourself. And it works reasonably well if the TZ environment variable is set, but it most commonly isn’t; readlink of /etc/localtime works on macOS and some Linux distros… but others make /etc/localtime a regular file not a symlink, which makes it all a lot harder
And that’s POSIX. Then there’s Windows which is possibly the last platform to still use its own timezone database instead of IANA’s. Now, Unicode CLDR maintains a Windows-to-IANA mapping table… but you have to ship both that table, and maybe the IANA timezone DB too, with your app, and keep them updated
I really wish Microsoft would ship the IANA database with Windows, and the IANA-Windows mapping table too, and provide APIs to query them, and keep them updated with Windows update. The core Windows OS and existing Windows apps can keep on using the legacy Windows TZ database for backward compatibility, whereas portable apps could use IANA instead if they wish
> I really wish Microsoft would ship the IANA database with Windows, and the IANA-Windows mapping table too, and provide APIs to query them, and keep them updated with Windows update.
I think they have done exactly what you describe for several years at least:
That’s a .Net API, so not easily usable from native code. If they offered a C API instead, almost anything could feasibly use it.
Plus, from reading that doc, it sounds like it only works on Windows if you enable “App-Local ICU” mode, in which case the ICU DLL is added to your .Net app’s distributable package - which implies the info isn’t actually bundled with Windows itself
Consider Python’s zoneinfo standard library module-it provides access to IANA TZ database. On all platforms except Windows it uses the copy of the DB bundled with the OS and updated by the OS update mechanisms. On Windows, you have to install a PyPI module containing it. If Microsoft bundled it with the OS, with a C (not .Net) API, you wouldn’t have to do that-but Microsoft doesn’t, so you do
You conceivably need more than that. You need to know the location (NOT just the time zone) where it will occur, the time zone that location was in when the meeting was created, and the time zone that location is in when the meeting actually happens. The users' systems or whatever does final display need to know their own time zone(s), and how to convert.
Say, for a somewhat annoying-case example, you want to store a meeting date/time that's in the future, in January, in the city of New York, New York, USA, with remote participants elsewhere in New York state. Sometime in between when the calendar invite is created and the meeting the city of New York decides to change to be on permanent Daylight Savings Time, but the rest of New York state doesn't change. If you stored only the UTC time and "America/New York" you now have an ambiguous meeting date/time, since the "America/New York" time zone split and the city of NY is an hour off from the rest of NY for part of the year, and your remote participants could get the wrong time.
There's probably an even worse case involving the death of a Japanese emperor, since the "period" portion of a Japanese date is the imperial name of the emperor who ruled at that time, and that gets retroactively applied to dates between when the new emperor's coronation and when they took their new imperial name.
You still need the timezone name to map back to UTC, in case you want to make some types of computations, usually along the lines of "how long ago was this" and "remaining time until this thing happens".
You may argue that we can use local time to make the computations and be done with it, but during DST transitions, local time jumps so the number of actual seconds won't be consistent.
The post doesn’t account for the case where a suburb of Amsterdam breaks off from the rest of Netherlands and changes timezones… Then how do you know if the event was in the neighborhood or not?
My point is that this is an extremely niche case and works around one particular type of timezone insanity. You either have a team dedicated to dealing with timezone insanity, or you store stuff in UTC.
The list of things that devs should "never ever" do grows by the day... turns out most things, even the simplest of things, even sometimes the most apparently trivial things (like naming of people, too) are in reality almost always much more complex and difficult to get right on the first go than expected.
But then discussion ensues about how programmers these days add libraries as dependencies for almost everything! :-)
I guess at some point a middle ground must be found.
Or if you really want to be future proof, store the geolocation so you can try to figure out the jurisdiction for any changing regulations. Maybe they didn't change the date of the switch, but changed the timezone boundary on the map.
But, then I guess we might need to account for fractured societies and actually store some kind of organizational code for which belief system the event author adheres to? :-)
You jest, but there are three calendars in active daily use in close enough proximity to me that it is not unheard of for mistakes to happen. Especially in the evening, as not all calendars start the new day at the same hour!
Internally everything is stored and handled in TAI (better than UTC as no discontinuity) and translated from/to something else for human consumption.
I.e. for instance your should have logic to figure out what TAI period corresponds to "next month's meetings" if that's what the user wants, which you apply immediately on user inputs and then forget about DST, time zones, etc. in the rest of the code and storage.
Another benefit is that if your user was in New York but is now in London it is trivial and well-constrained to adjust to local time.
Some use cases really do require the local TZ offset be saved. Transforming everything to UTC wipes out that information.
An engineer in the US reviewing industrial measurements logged in a plant in Asia from a variety of sources is definitely going to encounter lots of events recorded in local time. It would be maddening for that engineer to have to review and resolve events from different time coordinates, especially if they are doing the review months or years later. It's best to accept that reality and adopt local time as the standard. Then you must record the TZ offset per UTC in any new system you create.
Usually the TZ offset is enough. The use case is a guy reading notes and logs from multiple sources. All that guy needs is to see the local time at the time and place of the event. So that, for example, he can match up the time stamp on some computer recorded log with the time some human operator recorded, in local time, on a paper record.
I always felt the answer to this question is both, since there is always yesterday and tomorrow as far as lunch is concerned, so everything by definition is both before and after lunch. Perhaps the question is ill formed and needs to ask if the time was before, during or after lunch, during the day of the timestamp while defining what during means. That would have a more normal answer.
It is unclear to me. It has been ever since I was a child. This is what happens with periodicity. There is no 1 lunch reference point when you just say lunch in this sort of question.
You're not alone, believe me, but one of the things you have to learn at some point is that for the vast majority of the population the question is perfectly clear. This is an example of the midwit meme, something like this:
IQ 55: it happened before lunch,
IQ 100: "lunch" isn't a time, lunch for whom? And which lunch? Their first ever lunch? Do babies even have lunch?
Usually, people with higher IQs are the ones who have trouble with such things. There is a logical difference between “before lunch” and “before lunch that day”. This is similar to how higher IQ individuals see the Monty hall problem as having a 2/3 probability rather than a 1/2 probability in the famous version of the problem posed to Marilyn vos Savant. They are often derided as being idiots for not having “common sense”, even when their remarks are correct.
That said, IQ is considered obsolete given the theory of multiple intelligences. IQ only covers a subset of it.
The problem with that is you lose the localtime information, which you may want. Say you have recorded the localtime with the known UTC offset of 0, and that localtime is midnight UTC. Now you want to map it back to a localtime in the past. Ok, which localtime? Was it 8pm in NYC? Or was it 5pm in LA? Is the assumption that the localtime is wherever the user is right now, and is that a valid assumption? If the user has traveled to a different timezone, the time is now being converted to a localtime in the past that is different than it actually was when it happened.
> If the user has traveled to a different timezone, the time is now being converted to a localtime in the past that is different than it actually was when it happened.
For most cases I think that would be correct, but I will say if I am looking at my ATM withdrawals for a trip I made to San Francisco, I would like the time shown to be the SF time and not that of my local hometown, and vice versa if I'm in SF.
Cloudist helps partners to offer Green Cloud services to their customers. The product you'd be working on would be a portal backed by an API allowing for clients to spin up VMs, provision S3-compatible storage buckets etc. Think AWS Console and API, but of course in a smaller scale.
We're a small, boot-strapped, profitable startup with an interesting voyage ahead of us.
This is a full-time (i.e. non-contractor) position, and we require you to be able to commute into our Malmö office several days a week. You should have a permanent work permit in EU and proven experience working face-to-face in EU-based teams. I.e. we offer no work visa sponsorship.
Cloudist helps partners to offer Green Cloud services to their customers. The product you'd be working on would be a portal backed by an API allowing for clients to spin up VMs, provision S3-compatible storage buckets etc. Think AWS Console and API, but of course on a smaller scale.
We're a small, boot-strapped, profitable startup with an interesting voyage ahead of us.
This is a full-time (i.e. non-contractor) position, and we require you to be able to commute into our Malmö office several days a week. You should have a permanent work permit in EU and proven experience working face-to-face in EU-based teams.