ecma402
ecma402 copied to clipboard
Unicode is planning to deprecate H24. What should browsers do?
Background: The H24 hour cycle is one where the first hour of the day is labeled 24, the second hour is labeled 01, and the last hour is labeled 23. The H23 hour cycle is one where the first hour of the day is labeled 00, the second hour is labeled 01, and the last hour is labeled 23. All locales that use 24-hour clocks currently use the H23 hour cycle; we are not aware of any that use the H24 hour cycle.
In https://unicode-org.atlassian.net/browse/CLDR-18303, the CLDR Design WG is recommending to deprecate the H24 hour cycle.
ICU4X currently decided to not support the H24 hour cycle.
The H24 hour cycle is a footgun and is likely to not be noticed by testing since it differs from H23 in only one hour of the day (the first hour).
What should browsers do?
For example, in all browsers, you can currently write the following code:
// Formats with the 24-hour clock where the first hour is hour 0
new Date(0, 0, 0, 0, 0, 0).toLocaleTimeString("en-u-hc-h23")
'00:00:00'
// Formats with the 24-hour clock where the first hour is hour 24
new Date(0, 0, 0, 0, 0, 0).toLocaleTimeString("en-u-hc-h24")
'24:00:00'
// Formats with the locale's default hour cycle, since H25 is not a valid hour cycle
new Date(0, 0, 0, 0, 0, 0).toLocaleTimeString("en-u-hc-h25")
'12:00:00 AM'
There are a few approaches we could take:
- H24 falls back to locale default behavior, similar to how H25 currently behaves. This means that users who currently use H24 will start seeing a 12-hour clock in some locales.
- H24 falls back to H23 behavior.
- We keep supporting H24. This means ICU4X needs to start supporting it, even though it is legacy.
- We throw an exception. However, H25 continues to behave as it currently behaves.
I'd like us to focus on which options are acceptable to us.
If we don't want to break the web, I don't see a way for us to land on (1) or (4). Do we consider (2) to be breaking the web or do we consider it to be a bug fix?
CC @robertbastian @markusicu @richgillam @younies @hsivonen
Is there any way to find out if developers actually -- mistakenly -- use h24?
Approach 1: If h24 is not supported as specified, then falling back to h12 in many locales would be a good "fail fast" mode. IMO better than...
Approach 2: ... mostly getting the same result as specified, but sometimes not.
Approach 3 is obviously acceptable.
Approach 4 depends on whether there is significant usage.
I did some googling:
-
MDN does point out that
h24is not used anywhere: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getHourCycles#supported_hour_cycle_types -
There is also a
hour12flag, which sounds like it is already not consistent across browsers, and nothing burned down so far (Stackoverflow post from 2021, MDN) -
Here's an interesting comment: "
h24must be used with caution. It would have been nice if the date part was the value one day before." -
lots more stackoverflow posts where people get confused by
h24
I think falling back to h23 is the least worst option here.
PS: We are looking at deprecating h24 because it is not used in CLDR data, which means we don't know of a real use case. It is still possible that someone is using it explicitly and does expect it to do what it has always done. One more reason why not supporting it would be better than suddenly treating it like h23.
And if the cost of supporting h24 as intended is very small, then maybe we should just support it.
The argument in favor of treating h24 as an alias of h23 is that when developers wrote h24, they probably* intended it to have the behavior of h23, so we are simply aligning the behavior to match user expectations.
* We could acquire data on this if necessary.
I don't think option 4 is a good idea. That'll cause everybody more pain than any of the other options.
The arguments in favor of 1 and 3 are that h24 has been out there for a long time and changing its definition is likely to lead to confusion AND that it'll bite us if we ever DO find a real use case for its old meaning in the wild. Furthermore, making h24 mean the same thing as h23 is confusing to anyone who already knows about h11 and h12 and how they're different from one another.
The argument in favor of 2 is that in all this time, we haven't found a real use case for h24. Nobody uses it, and all the people who are using h24 probably meant to use h23 and just didn't read the documentation or notice their code was formatting midnight funny. Given that h24 has no real-world use, why not just give people what we're pretty sure they really wanted?
I find myself coming down very close to the border between these two arguments. The argument for changing a longstanding behavior generally centers on "the old behavior was just flat wrong and not useful or caused problems." This isn't that, but it's not far off. On the other hand, I have little patience for "it breaks the Web" arguments, where we have to support something in perpetuity because too many people out there took advantage of wrong or undocumented behavior (and if if that argument holds up, does this really rise to the level of "breaking the Web," or is it just a couple Web sites?). If "it breaks the Web" is going to be the final argument, I see that as an argument for option 3, not option 2.
Forced to make a decision, I'm still on the side of options 1 and 3, but not entirely unsympathetic to option 2. But I'm frustrated that we're still going around in circles about this. We were awfully close to a consensus this morning, and yet here we are.
Why would option 4 cause pain? Wouldn't it just surface the problem early and loudly, so it can be fixed?
I think we should make h24 act as an alias of h23.
Every time I've seen h24 in the wild (i.e. outside examples contrasting h23 and h24), it's been a mistake where h23 semantics were intended. (Reminder that h24 is so confusing that ECMA-402's eponymous issue was about a spec bug around h24 that propagated to unwanted behavior in V8.)
Why would option 4 cause pain? Wouldn't it just surface the problem early and loudly, so it can be fixed?
It would surface loudly to users who are not empowered to fix it, and even surfacing it to the Web developer causes busy-work for the Web dev, since the engine already knows what the fix is (treating it as h23).
The only potential usecase I have for h24 is to display the end of a time range at midnight.
So range over a full day is 00:00 - 24:00.
But that currently needs special handling anyway.
The only real-world use of 24:00 as a time that I'm aware of is in Japan's 30-hour system, where closing times past midnight until 6am may be indicated by times starting with 24, 25, 26, etc. as the hour.
However, these times are not in general supported by h24 either.
And, as the one stackoverflow user noted, 00:30 on Friday should be 24:30 on Thursday, but h24 would return 24:30 on Friday. So it does not even match the Japanese usage.
TG2 discussion: https://github.com/tc39/ecma402/blob/main/meetings/notes-2025-08-14.md#unicode-is-planning-to-deprecate-h24-what-should-browsers-do-1002
The sentiment of the room was that in the web platform we should make -u-hc-h24 fall back to -u-hc-h23, regardless of what CLDR decides to do. @hsivonen explained why most eloquently: because the primary constituency is the end user, and if the end user is currently getting a 24-hour clock, they should continue getting a 24-hour clock.
For example, support a calendaring application has a toggle switch for the user's preferred hour cycle. The app might not have been updated in 5 years, but it still works fine. If the app had a bug where they were using h24 instead of h23, it would hurt the users of the Web if we made it start printing out 12-hour time.