gotchajavascriptMajor
Timezone handling — an offset is not a timezone
Viewed 0 times
timezoneIANADSTUTC offsetdaylight savingAmerica/New_York
Problem
Developers store or display dates using a UTC offset like +05:30, assuming it represents a timezone. Offsets change with DST. Code that bakes in an offset breaks twice a year for affected regions.
Solution
Use IANA timezone names (e.g. 'America/New_York') with Intl.DateTimeFormat, not numeric offsets.
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/New_York',
dateStyle: 'full',
timeStyle: 'long',
});
fmt.format(new Date()); // Correct for DST automatically
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/New_York',
dateStyle: 'full',
timeStyle: 'long',
});
fmt.format(new Date()); // Correct for DST automatically
Why
IANA timezone names encode the full DST transition history. An offset like -05:00 is ambiguous across regions. A name like 'America/Chicago' resolves correctly for any date.
Gotchas
- JavaScript's Date object has no timezone — it stores UTC internally and renders in local time
- getTimezoneOffset() returns the LOCAL machine's offset, not a stored timezone
- Storing a UTC timestamp plus an IANA name is the correct pattern for future events
- For past events a UTC timestamp alone is sufficient
Code Snippets
Timezone-correct formatting with Intl
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/Chicago',
hour: 'numeric',
minute: '2-digit',
hour12: true,
});
fmt.format(new Date('2024-07-01T17:00:00Z')); // '12:00 PM' (CDT)
fmt.format(new Date('2024-01-01T17:00:00Z')); // '11:00 AM' (CST)Revisions (0)
No revisions yet.