by omnicognate | 2025-09-07 09:58:15+00:00
The vast majority of them really should be points in time. The correct name for a (date)time that isn't is a "nominal" or "naive" date(time), not a local one. Nominal (date)times do indeed have valid use cases, but they are rare.

Taking your example of an appointment, a nominal (date)time would be appropriate if the meeting were to take place at a particular local time but in an as-yet unspecified geographical location, which will be specified later. The form of the appointment would be "we will meet at 13:00 according to the local convention in the place where the meeting actually happens, which is yet to be determined". Here, a nominal time would be appropriate, but note that it would need to be paired with some geographical information prior to the appointment taking place in order to identify a point in time, allowing the meeting to go ahead.

The above is a very unusual situation, though. It's far more likely that the meeting will be either in a location known up front or in no particular location (eg. if it's a video call with participants in multiple countries).

In the first case, the correct thing is to include the geographical timezone of the location where the meeting will take place. For example, if the meeting is in London the timezone would be Europe/London. You raise the concern that the local convention could change, eg. daylight saving time could be abolished, but that isn't an issue. The "whatever the convention is in operation in London at that time" part is captured in the use of Europe/London as the timezone, and there would be no need to update the (date)time if the convention changes. The (date)time identifies an instant in time as long as the convention doesn't change, but if the convention does change it automatically reflects it.

In the second case we need to define an instant in time so that people know when to attend the meeting. This could be done with a count of milliseconds from an agreed reference instant, but that's not very user friendly. The correct thing to use here is a (date)time with a defined timezone. If there really is no favoured location UTC would be the obvious choice, but any preferred timezone could be used as long as it's indicated in the (date)time so that the specific instant can be resolved. You might want to avoid using a zone like "Europe/London" whose convention could potentially change, although if you did use it the instant at which to to connect would still be well defined at the time of the meeting.

You rightly point out that nominal datetimes don't define instants in time, but that's why you should avoid them. Most use cases should specify a point in time, at least up to local convention in a specific location. Genuine use cases for nominal (date)times are rare. In the vast majority of cases where they are used a timezone really should have been specified. This mistake is extremely common, and it doesn't remotely surprise me if some programmers at Apple have made it.

A brief note on "local" times. These aren't the same thing as nominal times. A local time has an implicit timezone that is the local one according to the current locale. Local (date)times therefore do specify particular instants in time. One of the biggest mistakes people make is to write out local (date)times as nominal (date)times to stores that can be read by code running with different locales. This causes many problems. If you write out a local (date)time include the current time zone!

I ask you please to learn from the above. I know it's hard to prevent comment exchanges turning into arguments, but I'm not trying to win points here. I've taken a chunk of my Sunday morning to explain something I don't find terribly exciting in the hope that the knowledge will benefit anyone who reads it. I really hate being in a situation where I have a timestamp from a log or db or on the wire or something and whoever put it there didn't think to include the information needed to interpret it correctly. It happens to me distressingly often at work. Let's all do better.

Edit: Worth noting that ISO 8601 doesn't allow timezones like Europe/London. That's disappointing but doesn't relieve you of the duty to include the timezone information when persisting (date)times. It just makes it slightly more awkward. Good date/time libraries do support these zones.