Timezone Offsets in Timestamps
Learn how timezone offsets work in timestamps, the difference between offsets and timezone names, and how to handle offset-aware date strings correctly.
Concept
+09:00
Detailed Explanation
A timezone offset indicates the difference between local time and UTC, expressed as ±HH:MM. For example, +09:00 means the local time is 9 hours ahead of UTC (used by Japan Standard Time and Korea Standard Time). The offset -05:00 means 5 hours behind UTC (US Eastern Standard Time).
Offset format variations:
+09:00 ISO 8601 standard (with colon)
+0900 RFC 2822 style (without colon)
+09 Shortened (hours only, allowed in ISO 8601)
Z Zero offset (equivalent to +00:00)
Offset vs. timezone name — a critical distinction:
An offset like +05:30 tells you the current difference from UTC, but it does not tell you which timezone rules apply. India Standard Time (IST) is always +05:30, but "IST" could also mean Irish Standard Time (+01:00). More importantly, a timezone name encodes DST rules: America/New_York is -05:00 in winter but -04:00 in summer. An offset alone cannot represent this change.
2024-01-15T09:30:00-05:00 → Eastern Standard Time (EST)
2024-07-15T09:30:00-04:00 → Eastern Daylight Time (EDT)
Both are: America/New_York
Practical implications:
When parsing a timestamp with an offset, you can always convert it to UTC accurately. But you cannot reconstruct the original timezone from the offset alone. If you need to know the user's timezone for future calculations (scheduling recurring events, for example), store the IANA timezone name alongside the timestamp.
Common pitfalls:
JavaScript's Date object loses timezone information — it always converts to UTC internally and displays in the runtime's local timezone. To preserve the original offset for display, you need to use Intl.DateTimeFormat with an explicit timeZone option, or a library like Luxon or Temporal (the upcoming TC39 standard).
Working with offsets in code:
// JavaScript: Get current offset in minutes
new Date().getTimezoneOffset() // -540 for +09:00 (note: sign is inverted!)
The inverted sign in JavaScript's getTimezoneOffset() is a notorious source of confusion — a positive offset returns a negative number.
Use Case
When building a meeting scheduler for international teams, storing timezone names rather than just offsets ensures that recurring meetings adjust correctly when participants' DST rules change.