Compute "today" and date-picker bounds in local time, not UTC
todayISO() and day.js's stepDay() formatted dates via toISOString(), which is UTC. For UTC+ viewers past local midnight this rolled the date a day early: "today", the date-input max, the next-day disabled guard, and the Weekly "Today" button all referred to the wrong day, and prev/next navigation stepped off-by-one. Route both through the existing local isoOfDate() so every view (Weekly, Day Detail, Calendar) agrees on the viewer's local day.
This commit is contained in:
parent
248eeee110
commit
f0747bae3a
2 changed files with 8 additions and 3 deletions
|
|
@ -7,7 +7,7 @@ import { uv } from "./account.js"; // header sign-in entry + notification bell
|
||||||
import { getJSON, TTL, prefetchViews } from "./cache.js";
|
import { getJSON, TTL, prefetchViews } from "./cache.js";
|
||||||
import { initFindButton, setFindLabel } from "./mappicker.js";
|
import { initFindButton, setFindLabel } from "./mappicker.js";
|
||||||
import { TIER_COLORS, PRECIP_COLORS, DRY_COLOR, pctOrd, fmtPrecip, fmtWind, fmtHumid,
|
import { TIER_COLORS, PRECIP_COLORS, DRY_COLOR, pctOrd, fmtPrecip, fmtWind, fmtHumid,
|
||||||
todayISO, weatherType, placeLabel } from "./shared.js";
|
todayISO, isoOfDate, weatherType, placeLabel } from "./shared.js";
|
||||||
|
|
||||||
// Color a tier the same way the calendar cell would be colored for it.
|
// Color a tier the same way the calendar cell would be colored for it.
|
||||||
const tierColor = (c) => (c === "dry" ? DRY_COLOR : TIER_COLORS[c] || PRECIP_COLORS[c] || "");
|
const tierColor = (c) => (c === "dry" ? DRY_COLOR : TIER_COLORS[c] || PRECIP_COLORS[c] || "");
|
||||||
|
|
@ -44,7 +44,9 @@ function stepDay(delta) {
|
||||||
if (!curDate) return;
|
if (!curDate) return;
|
||||||
const d = new Date(curDate + "T00:00:00");
|
const d = new Date(curDate + "T00:00:00");
|
||||||
d.setDate(d.getDate() + delta);
|
d.setDate(d.getDate() + delta);
|
||||||
const iso = d.toISOString().slice(0, 10);
|
// Format in LOCAL time — curDate was parsed as local midnight, so toISOString()
|
||||||
|
// (UTC) would shift the result a day for UTC± viewers and desync the today guard.
|
||||||
|
const iso = isoOfDate(d);
|
||||||
if (iso > todayISO()) return; // don't step past today
|
if (iso > todayISO()) return; // don't step past today
|
||||||
curDate = iso;
|
curDate = iso;
|
||||||
fetchDay();
|
fetchDay();
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,10 @@ export const pctOrd = (n) => {
|
||||||
if (!Number.isFinite(v)) return "—";
|
if (!Number.isFinite(v)) return "—";
|
||||||
return ord(Math.min(99, Math.max(1, Math.round(v))));
|
return ord(Math.min(99, Math.max(1, Math.round(v))));
|
||||||
};
|
};
|
||||||
export const todayISO = () => new Date().toISOString().slice(0, 10);
|
// Today in the viewer's LOCAL zone (see isoOfDate below). A UTC date rolls a day
|
||||||
|
// early/late for UTC± viewers past local midnight, putting "today" and the
|
||||||
|
// date-picker max out of reach of the day they're actually living in.
|
||||||
|
export const todayISO = () => isoOfDate(new Date());
|
||||||
export const esc = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
export const esc = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||||
// The heading label for a graded response: the resolved place name, or the
|
// The heading label for a graded response: the resolved place name, or the
|
||||||
// cell-center coordinates while (or if) no name resolves.
|
// cell-center coordinates while (or if) no name resolves.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue