Picking a clock picks its separator too
24-hour read as 13.45 in Denmark, because that is how Danish writes a clock and toLocaleTimeString was doing as it was told. But somebody who leaves "follow the region" and picks 24-hour has just said they want the region to stop deciding — and they mean 13:45. So the two explicit modes build the string from formatToParts and pin the mark between the hour and the minute. Only that one literal is replaced: everything else stays the locale's, which is why Japanese keeps 午後 in front of it and English keeps its lowercase pm after. 12-hour got the same for free — it had the identical 01.45 pm. Auto is left alone. A setting that says to follow the region has no business arguing with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4d51a34c44
commit
263d35c688
@@ -92,11 +92,29 @@ export function formatTime(value) {
|
||||
const d = value instanceof Date ? value : new Date(value);
|
||||
if (isNaN(d)) return "—";
|
||||
const opts = { hour: "2-digit", minute: "2-digit" };
|
||||
if (prefs.timeFormat === "24") opts.hourCycle = "h23";
|
||||
else if (prefs.timeFormat === "12") opts.hourCycle = "h12";
|
||||
const mode = prefs.timeFormat;
|
||||
if (mode !== "24" && mode !== "12") {
|
||||
// Auto is the region's, whole: 13.45 is how Danish writes a clock, and a
|
||||
// setting that says "follow the region" has no business arguing with it.
|
||||
return d.toLocaleTimeString(prefs.locale || undefined, opts);
|
||||
}
|
||||
|
||||
// Asking for a clock outright is asking for its separator too. Somebody who
|
||||
// picked "24-hour" means 13:45, not the 13.45 their region would have written
|
||||
// — the point of leaving auto was to stop the region deciding. Only the mark
|
||||
// between the hour and the minute is pinned: the rest is still the locale's,
|
||||
// including whether there is an am/pm marker, what it reads and where it sits.
|
||||
opts.hourCycle = mode === "24" ? "h23" : "h12";
|
||||
const parts = new Intl.DateTimeFormat(prefs.locale || undefined, opts).formatToParts(d);
|
||||
return parts
|
||||
.map((p, i) =>
|
||||
p.type === "literal" && parts[i - 1]?.type === "hour" && parts[i + 1]?.type === "minute"
|
||||
? ":"
|
||||
: p.value
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
// Every number we render goes through here so the grouping separator follows
|
||||
// the user's chosen region rather than the browser's own locale — otherwise the
|
||||
// odometer disagrees with the dates and costs beside it.
|
||||
|
||||
Reference in New Issue
Block a user