Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here are two counter examples that sprang to mind:

1. I've set my alarm for 8am local time every day. I don't want my alarm clock to go off at 3am just because I'm in a different country

2. If I have an appointment at 10am next November, that's actually a datetime with a locale (given that my appointment is at 10am local time, no matter whether the DST rules change between now and then).



Well, you'll need another type meaning "local time" for #1. That's not a time without time zone, it's an entirely different thing.

Most environments simply can't represent that thing. They never could. With those changes this becomes more obvious, and with some luck people will finally fix this.

(The most absurd case is the "timestamp with local time zone" from SQL, that reads exactly like what you want, but represents a timestamp in a specific time zone, that is discoverable but mostly unknown.)


"8AM local time" is exactly time without a timezone. It's not datetime without timezone, but that's a different question.


Well, you seem to have some weird definition for the word "exactly".

"8AM" is exactly time without a timezone. "8AM at local time (local defined by this procedure)" isn't exactly that.

Perhaps you mean something like homomorphic. It is almost perfectly homomorphic. But if you define your types that way, you'll push yourself into the most useless ones you can get quite quickly.


At my last job we had types for a `Time.t` (time + date + timezone), a `Date.t` (just a day of the year), and a `Time.Ofday.t` (a time of the day with no timezone or date attached - like 8:00 AM).

This worked really well! You represent (1) with a `Time.Ofday.t`. I suppose if you wanted you could represent (2) with a `Time.Ofday.t` + a `Date.t`, although it kinda seems to me like you want to keep timezone information around if you're dealing with DST changes.


I think ISO 8601 made a big mistake by allowing timezone-less representation[1]. They should have used L for local time so it's explicit, and not allowed any timezone-less representation.

Sure it's technically well-defined as it is, but I think it's too important not to be written out.

In that case you can represent your alarm either as 08:00L if you want to wake up in the morning regardless of where you travel, or 08:00-02 for those cases where you need to stay in sync with home say.

[1]: https://en.wikipedia.org/wiki/ISO_8601#Local_time_(unqualifi...


I completely disagree, the local time is the only useful part of ISO 8601.

The big problem here is that it does not use timezones, but UTC offsets. Timezones can and do change their UTC offsets, completely breaking all future timestamps saved in ISO 8601-with-"timezones". "08:00 UTC-02" is ambiguous, "08:00 America/Nuuk" is not.


Fair point, but in that case it needs both. Offsets for recording historical timestamps, named zones for future time.

After all, if a zone changes offset today it shouldn't change the timestamp I recorded yesterday.


You don't need both. Named zones can do everything that offsets can, and it's still useful to know the named zone for historical timestamps in many situations.

> After all, if a zone changes offset today it shouldn't change the timestamp I recorded yesterday.

That's not how named timezones work. That behavior would be bad and it would also qualify as ambiguous.


How do you resolve timestamps around the time the offset changes then? Give the new offset a unique name?


Time zone changes are scheduled in advance (though rarely it's not far in advance) and there is only a single rule in effect at any point in time.

Half the world experiences a scheduled offset change every time summer time begins or ends. Computers can handle those fine.


> Half the world experiences a scheduled offset change every time summer time begins or ends.

But they do so because they record the actual offset when the time is recorded. If I send you 2023-10-29T02:15NO, how do you know if it's +01:00 or +02:00? Similarly, if Norway suddenly decided to switch their offset to be 15 minutes back, how will you handle that when reading previously recorded timestamps?


> If I send you 2023-10-29T02:15NO, how do you know if it's +01:00 or +02:00?

I think instead you'd send a timestamp (unix or NTFS or TAI or other) annotated with "Norway", and you would not send the offset.

> Similarly, if Norway suddenly decided to switch their offset to be 15 minutes back, how will you handle that when reading previously recorded timestamps?

Am I that bad at explaining this?

If Norway changes their offset, they will change it as of a specific moment in time. Times before that moment use the old offset, times after that moment use the new offset. The timezone database doesn't just store one or two offsets for a location, it stores every offset that has ever been used.

Checking whether you're before or after 5am on Feb 29th 2024 for a 15 minute change uses the same code as checking whether you're inside any particular year's version of summer time.


> I think instead you'd send a timestamp (unix or NTFS or TAI or other) annotated with "Norway"

This is what I attempted to write with "2023-10-29T02:15NO" (NO being Norway's country code).

> Am I that bad at explaining this?

Could be I'm dense, and it's not my field of expertise.

Let's say Norway has decided to change it's offset from +01:00 to +01:15 at 2024-01-01T01:00:00Z. I have a process that records timestamps, and lets imagine it records them with the suggested named offsets instead of numerical offsets, in the format shown above.

Later next year, you look in the logs and see 2024-01-01T02:07:00NO. How do you know which time this is in UTC?

With numerical offsets this is simple, because it would either be recorded as 2024-01-01T02:07:00+01:00 or 2024-01-01T02:07:00+01:15. But when you just have NO, how to you convert the timestamp to UTC?


A Unix/NTFS/TAI timestamp would not be affected by the offset. Using Unix as the example:

2024-01-01T02:07:00+01:00_NO -> 1704071220_NO

2024-01-01T02:07:00+01:15_NO-> 1704070320_NO

The timestamp doesn't have to be UTC, but it should specifically not be local time. You should be able to convert it to UTC without knowing the offset or time zone.

So, done this way, storing time zone and no offset is unambiguous. And it gives you more information than storing an offset and no time zone.


Thanks, yes that makes sense. I was working under the assumption that ISO 8601 was meant to be human-readable. If you can forego that requirement, then the solution you present would work well indeed.


1. That isn’t date data. That’s just storing a local time.

2. That’s why you WANT time zones in this example. It will automatically stay at 10am instead of bouncing around when DST rules change.

I’ve never ever needed timezone-less dates. Even using UTC or timestamps, it’s still UTC.

A date without a time zone is like “10 inches” but without the inches so it’s just “10”. Absolutely meaningless. You start moving just “10” around without the units in your code and then your Mars Orbiter explodes.


>2. That’s why you WANT time zones in this example. It will automatically stay at 10am instead of bouncing around when DST rules change.

Respectfully, no - in my scenario, if I used a timezone then I would show up at the wrong time for my appointment: each locale that observes DST has two timezones: one for DST, one for non-DST (e.g. BST and GMT for the UK). If I record a 10am appointment as "10am BST" and my country changes the rules on daylight savings transition date between now and the appointment, then I will show up at the wrong time for my appointment. Whereas if my appointment is recorded as "10am Europe/London" then it's encoding the human reality of my appointment, and can be correctly converted to an Instant in time if the rules change.

It sounds to me from your reply that you are mentally modelling all datetimes as Instants. These are one key aspect of dates+times (and often all a lot of software needs - since it's usually referring to some point in time that has already passed, or a future point in time that is x seconds from some other Instant), but Instants don't cover everything required when working with dates and times.

>I’ve never ever needed timezone-less dates. Even using UTC or timestamps, it’s still UTC.

Try sketching out the design for a calendar application and I bet you'll very quickly run into a whole raft of datetime related logic you might never otherwise encounter. Think particularly about future events: some are fixed instants in time (e.g. a meeting with people across timezones), others aren't (e.g. a dentist appointment in your city - my second example above is an instance where the local time of the appointment is relevant, not the Instant in time that local time referred to when the appointment was made). How do you represent recurring events?


For the classes of problems that you mention, I consider them as separate data types entirely and they shouldn’t ever touch your timezone-aware date-times objects. They should be stored as a composite types of your date, maybe time, and target timezone.

If you can mix timezone-aware objects with non-timezone aware objects like you do in Python, it’s get pretty dangerous because people will just mix them willy nilly and add and subtract the timezone-aware parts and then you get some really subtle date/time bugs.

That’s why I believe either a date-time MUST have a timezone and for other cases, you need a specialty data type for your domain, possibly provided by your date/time library.


Christmas is on December 25. It is not on December 25 UTC, or any other particular time zone.


That’s not a date-time though. You would not store that using the same type-compatible objects as your regular date-times or that’s how you end up one day blowing up a Mars Orbiter.


Yes, you need both zoned and zoneless versions of dates and times. This is why e.g. java.time has both (and it has LocalDateTime for when you need to say Santa delivers presents at 00:00 on December 25).

Zoneless time is not a mistake. Using it when you meant to use a zoned time is.


Making it easier to use zoneless over zoned is a mistake, though. An even more grave one is making zoneless the default. Unfortunately, that's a mistake that we've made decades ago, and now we have to fix it in a way that deals with all the accumulated mess.

Really, though, this is a recurring lesson in software engineering: don't be in a rush to make something a default just because it's "obvious"; explicit is better than implicit. Strings are another example; we've treated them as arrays of characters for so long that it's still a common default semantics for indexing a string, except now what you often get instead is UTF-8 or UTF-16 code units rather than actual code points. All of which is likely not what you actually need - but what you do need depends so much on the task that it should always be explicit.


You do.

Python does not. It’s all one object and I think that was a terrible idea.


Christmas is on December 24 where I'm from.


Which days are recognized by an administrative region as holidays is an orthogonal concern from timezones. e.g. the US recognizes the 25th but spans multiple timezones.


> 1. I've set my alarm for 8am local time every day. I don't want my alarm clock to go off at 3am just because I'm in a different country

Without timezone, your clock would actually go off in the middle of the night when you are in a different country. Your clock does not know you change location (no timezone, no location-dependent time), so it will alarm you after exactly 24 hours since the last alarm, which, in another country, can be midnight.

> 2. If I have an appointment at 10am next November, that's actually a datetime with a locale (given that my appointment is at 10am local time, no matter whether the DST rules change between now and then).

If everyone is staying in your city, then that works great (sans catastrophic continental riff or meteorite strike). When at any point you involve more than one geographic location, then the appointment is meaningless without timezones.

Now, maybe it is actually the case that you and your software only care about one geographic location in perpetuity, but just like assuming 32-bit IP addresses, 8-bit ASCII, and length-oblivious arrays are all you need, the teeth marks from its consequential bite tend to be quite deep and sanguine.


> Without timezone, your clock would actually go off in the middle of the night when you are in a different country

Your clock would do what your clock is programmed to do. What a weird statement to make about a completely hypothetical tool.


> Without timezone, your clock would actually go off in the middle of the night when you are in a different country. Your clock does not know you change location

This does not describe any modern person's experience. Your clock is connected to the internet; it always knows the local time.


You're missing the point. Evaluating the rule requires a timezone, but the rule itself is not defined with reference to a specific timezone (well, the second one is assuming you can use something like PT that changes between PST and PDT throughout the year). To define the first rule requires a zoneless time.


1 could be better served by an integer representing the minute it should go off anyway, since there is no specific date attached

2 time zones account for DST so that point is moot, but in the context of traveling and still wanting to maintain the same times this is actually something calendar apps often get wrong


OK, you’ve convinced me that having a naive datetime object available makes sense

but are there any cases where “now” being naive is useful


No, I can't think of any case where that would be useful (although I do take umbrage with a local datetime being referred to as a 'naive' type - it serves a very specific purpose as a primitive... if it's naive then so is an int, since it does not specify a unit).

I don't know anything about Python's datetime handling (other then to be alarmed by it given what I've seen in this thread). I live in the Java world where the java.time library is one of the best around (after a decade or more of Java having one of the worst date time libraries)


datetime with locale is how timezones are represented in python. What you're asking for there is a datetime with a timezone, not a datetime without a timezone.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: