fix(events): midnight in an announcement is 12:00 am on the Node we ship #200
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/events-announce-midnight-hourcycle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This is the red X on
#199, and on every events PR since#192. One test, the same one, in all eight runs — each reported# fail 1, so nothing else was hiding behind it.The defect is in production, not in the test
startsAtLabelaskedIntl.DateTimeFormat('en-GB', { …, hour12: true }). That is not the same request as a 12-hour clock. For a locale whose default cycle ish23—en-GBis one —hour12: trueresolves toh11, whose hours run 0–11, so midnight renders0:00 am.hour12: trueresolves tonode:20-alpine— whatDockerfileships and CI runsh110:00 amh1212:00 amSame ICU (78.2) on both sides, so this is V8's ECMA-402 behaviour, not locale data — which is why no amount of matching the runner's locale would have found it. It is also why this rendered correctly in front of everyone who wrote it and wrongly for every real recipient: an event mail announcing a midnight start said "0:00 am" while the schedule editor beside it said "12:00 AM". One instant, two spellings — the exact contradiction the option was added to prevent, quoted in that comment.
The fix
hourCycle: 'h12'is the request that means what was meant.recurrence.js:71already states the mirror-image rule (hourCycle: 'h23'rather thanhour12: false, for the same reason in the other direction), and every other formatter in this repo and inmodule-uouseshourCycle.announce.jswas the onlyhour12left in either tree; now there is none.The comment beside it names the Node divergence, so the next person to read
hourCycledoes not "simplify" it back.Verification, on the runtime that actually fails
Run under
node:20-alpineagainst this tree:On Node 22+ the test passes either way, so the test's comment now says a green run on a dev machine is not evidence and CI is what holds this line.
8:00 pmand the bad-zone/bad-instant cases are unchanged.Two notes on what this is not: the other three red jobs in this cutover window were infrastructure, not code —
link's andservuo-plugins' release runs died in the Gitea outage at 19:53–20:03 UTC (error: 530pushing the tag; aSet up jobthat lost the server after 11m52s), andlink'srust-gatesfailures werecurl: (6) Could not resolve host: sh.rustup.rsinside the runner.Onto
edgeso#199picks it up (Phase 16b, step 2).🤖 Generated with Claude Code
https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4