- Ya
- 22 Agosti 2026, 11:28 UTC
- Mwandishi
- kamo
- Ahadi ya
- ec88120
A direct message sent at 3:33 AM Pacific displayed "10:33 AM" — the raw UTC clock, printed as though it were local. Two independent defects, present together on almost every surface that shows a time. THE PARSE. Every Java service stores timestamps as LocalDateTime and puts them on the wire with toString(): "2026-08-22T10:33:12.345", carrying no offset and no Z. The value is UTC, because the pods are, but the string does not say so — and ECMAScript reads an offset-less date-time as LOCAL. new Date() in a Los Angeles browser landed seven hours late, plausibly, silently, everywhere. THE RENDER. toLocaleTimeString() with no timeZone formats in the BROWSER's zone, a fact about the laptop. A member whose profile says Eastern working from a hotel in Denver must still read their records in Eastern. useFormatters() built every Intl.DateTimeFormat with no timeZone at all. app/lib/serverTime.ts is now the one place both are settled: parseServerDate / toServerDate / serverEpochMillis treat an offset-less string as UTC and pass a zone-bearing one through untouched; formatInZone and friends render in an explicit zone; a bare YYYY-MM-DD stays on the day it names instead of sliding back one for everyone west of Greenwich; zonedDayKey buckets by the member's day so a 6pm Pacific message stops filing itself under tomorrow. The zone itself is resolved SERVER-SIDE in the root layout and carried by MemberTimezoneProvider, so SSR and the client agree on the first render rather than flipping after hydration. useFormatters() binds it, and 175 components now take it from there. timezoneService is superseded and documented as such: it reads ***'s TZ, which PostAuth***Service fills from the USERS row rather than the member profile, then caches it in localStorage forever — which is why correcting a profile timezone appeared to do nothing until site data was cleared. Not only cosmetic. Chat read receipts were compared against message timestamps on two different clocks, and that comparison decides whether "unsend" or "revoke attachment" is offered. callbackUrgency and dueUrgency answered "is this due today" on the browser's calendar; both now take the member's zone, and their tests name it rather than depending on where the suite runs. **************** is wired into npm test and fails the build on a new occurrence of either defect — including the Date.parse and Intl.DateTimeFormat spellings. A test cannot catch this alone: fixtures get built with toISOString(), which appends the Z production does not send, so the suite passes while the app is hours out. Genuine exceptions (a wall-clock the member typed, a calendar date anchored at noon UTC) carry a serverTime-ok comment saying why.