mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-18 09:08:06 +00:00
fix(web): sample both sides of DST when comparing zones
CodeRabbit caught this and it is right: comparing the wall clock at one instant treats zones that merely coincide right now as the same one. America/New_York and America/Lima hold the same offset all winter, so a panel set to the wrong one of the two ticked the step in January and then ran an hour off from March -- a silent false pass, which is the failure the whole check exists to prevent. Same shape as the dateStyle problem in the previous commit: a comparison coarser than it looks. Three instants now, all of which must agree: now, and mid-January and mid-July of the current year. Those sit either side of DST in both hemispheres, so only zones that agree year-round match. Toronto still matches New York, which is correct -- either renders the same times. Two tests. A static one asserts the comparison samples more than the current instant, since reverting to `[now]` looks like a simplification. And a table pinning which pairs must count as the same zone: aliases and same-rule zones equal, seasonal coincidences (New York/Lima, Phoenix/Los_Angeles, Sydney/Guadalcanal) not. That table mirrors the algorithm rather than executing the shipped JS -- there is no JS runtime here and the repo has no JS test infra -- so it records the verdicts the browser code has to reach, and the static guard keeps the two aligned. Mutation-checked: reverting to a single instant fails the static guard. Also documented what the city test compares. CodeRabbit read it as always failing, on the grounds that the label differs between Tampa and Seattle. It does, but timezone_step() returns the opening tag only, so the comparison is over data-done and data-tz and the label is not in it. The assertion is left as an equality over the whole tag, which is stronger than checking the two attributes by name; the docstring now says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STMbQE4YctTacQXfbYqKuW
This commit is contained in:
co-authored by
Claude Opus 5
parent
dcba6120f9
commit
5a6dfbfc9a
@@ -184,13 +184,24 @@
|
||||
// the old test ticked it the moment the value stopped being the default.
|
||||
function sameZone(a, b) {
|
||||
if (a === b) return true;
|
||||
// Compare the wall-clock time each zone yields for one instant, not
|
||||
// the identifiers: aliases (Asia/Calcutta vs Asia/Kolkata,
|
||||
// Europe/Kiev vs Europe/Kyiv) name one zone and must not read as a
|
||||
// mismatch.
|
||||
// Compare the wall-clock time each zone yields, not the identifiers:
|
||||
// aliases (Asia/Calcutta vs Asia/Kolkata, Europe/Kiev vs Europe/Kyiv)
|
||||
// name one zone and must not read as a mismatch.
|
||||
//
|
||||
// Sampled at three instants, all of which have to agree. Checking only
|
||||
// now is not enough: America/New_York and America/Lima hold the same
|
||||
// offset all winter, so a panel set to the wrong one of those would
|
||||
// tick in January and then run an hour off from March. Mid-January and
|
||||
// mid-July sit either side of DST in both hemispheres, so only zones
|
||||
// that agree year-round match -- while Toronto still matches New York,
|
||||
// which is right, since either renders the same times.
|
||||
try {
|
||||
var now = new Date();
|
||||
var stamp = function (tz) {
|
||||
var year = now.getUTCFullYear();
|
||||
var instants = [now,
|
||||
new Date(Date.UTC(year, 0, 15, 12)),
|
||||
new Date(Date.UTC(year, 6, 15, 12))];
|
||||
var stamp = function (tz, at) {
|
||||
// Explicit numeric fields rather than dateStyle/timeStyle:
|
||||
// those are late additions to Intl (Firefox shipped them in
|
||||
// 91), and an implementation that does not know them ignores
|
||||
@@ -203,9 +214,14 @@
|
||||
timeZone: tz, year: 'numeric', month: '2-digit',
|
||||
day: '2-digit', hour: '2-digit', minute: '2-digit',
|
||||
hour12: false
|
||||
}).format(now);
|
||||
}).format(at);
|
||||
};
|
||||
return stamp(a) === stamp(b);
|
||||
for (var i = 0; i < instants.length; i++) {
|
||||
if (stamp(a, instants[i]) !== stamp(b, instants[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
// An unparseable zone in the config is worth surfacing, not hiding.
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user