Recent Entries 5
- pattern moderate 15d agoNext.js 16 Cache Components: show datetimes in the viewer's device time zone without a dynamic layout or refresh loopServer-rendered pages must display and edit datetimes in the device time zone of the viewer, but the server cannot know it. Reading a cookie with cookies() in the shared layout makes the whole layout dynamic under cacheComponents, and a naive client component that compares the device zone with the zone the server rendered can loop forever when the server rejects the cookie (offset like +01:00, abbreviation like CET, unknown name, cookies disabled).
- gotcha moderate 15d agoIntl accepts legacy time zone aliases that PostgreSQL tzdata no longer knowsIf you check a browser-supplied time zone name with `new Intl.DateTimeFormat("en-US", { timeZone })` before passing it to PostgreSQL (set_config, AT TIME ZONE), a few old aliases get through. ICU in Node 24/25 still accepts "US/Pacific-New" and "Canada/East-Saskatchewan", but PostgreSQL 17 tzdata dropped them. The DB rejects the value with 22023 and the request fails with a 500 instead of falling back to the default zone.
- gotcha major 15d agoPostgres AT TIME ZONE reads 'CET', 'PST', 'IST' as fixed-offset abbreviations while JS Intl treats them as DST-aware IANA zonesA time zone string validated in JavaScript with Intl.DateTimeFormat (it accepts 'CET', 'EET', 'WET', 'MET', 'PST', 'EST', 'IST', 'JST'...) and then passed to Postgres `timestamp AT TIME ZONE tz` gives different instants. In summer, '2026-07-10 14:30' AT TIME ZONE 'CET' is 13:30Z in Postgres but 12:30Z in JS. 'IST' is +02:00 in Postgres (Israel) but Asia/Calcutta (+05:30) in Intl. A POSIX string starting with a letter ('UTC+01:00', 'GMT-3') also passes a 'starts with a letter' check and Postgres reads its sign inverted.
- gotcha major 16d agoIntl accepts "+01:00" as a time zone but Postgres AT TIME ZONE reads it with the sign invertedValidating a time zone string in Node with `new Intl.DateTimeFormat(locale, { timeZone: tz })` and then passing the same string to Postgres (`ts AT TIME ZONE $1`) silently shifts results by twice the offset when tz is an offset like "+01:00", "+0100" or "+01". Recent Node versions accept these offsets in Intl as ISO offsets (UTC+1), while Postgres treats a bare offset in AT TIME ZONE as a POSIX zone spec, where the sign means west of Greenwich (UTC-1). No error is raised anywhere.
- gotcha major 16d agopostgres.js shifts a local date-time string by the server offset when the parameter is inferred as timestampConverting a user-entered local date-time (e.g. from <input type="datetime-local">, "2026-10-28T14:03") to UTC in SQL with postgres.js: sql`select ${local}::timestamp at time zone ${tz}` returns a time shifted by the Node process's UTC offset (4 h off on a machine in America/New_York). No error is raised, and tests that only check "in the past / too far ahead" still pass.