How do you handle time zones: what do you store, send and show?
Predict first
What does this print?
let d = Date(timeIntervalSince1970: 0)
let style = Date.ISO8601FormatStyle(timeZone: TimeZone(identifier: "Asia/Kolkata")!)
print(d.formatted(style))
- 1970-01-01T00:00:00Z
- 1970-01-01T05:30:00+0530
- 1969-12-31T18:30:00-0530
Predict first
What does this print?
print(TimeZone(identifier: "Nope") as Any)
- nil
- UTC
- Crash
Mental model. The instant is a flight’s takeoff in GMT. Every passenger reads it off their own watch.
Store and send instants: UTC timestamps, epoch seconds, or ISO 8601 with a zone. Convert to a zone only when you show a time or do calendar maths that means something to a person.
Zones are named by IANA identifiers such as Asia/Kolkata. TimeZone(identifier:) returns nil for an unknown name. Abbreviations like “EST” are ambiguous, and a fixed offset (TimeZone(secondsFromGMT:)) knows nothing about daylight saving. TimeZone.current is a snapshot; autoupdatingCurrent follows the device. If an event happens in a place (a flight, a meeting room), save that place’s zone with it.
The same instant reads 05:30 on a clock in India (UTC+5:30), written with a +0530 offset. Nothing about the Date changed, only how it is shown.
An unknown identifier gives nil, so force-unwrapping a hard-coded name is a latent crash.
Common traps
- Saving a local time with no zone. You can never recover the instant, especially near a DST change.
- Using a fixed offset for a city. New York is -5 in winter and -4 in summer; only the identifier knows that.
They might follow up with
- How do you show “9 am in the user’s zone”? Keep the instant, then format it with a style or formatter whose time zone is the user’s.
- What changes when a user travels?
autoupdatingCurrentreflects the new zone; stored instants never change.
Related questions
- 2.2.1 What is a Date in Foundation, and what does it not contain?
- 2.2.4 Why is date + 86,400 seconds not tomorrow?
← What is a Date in Foundation, and what does it not contain? How do Calendar and DateComponents work, and why can YYYY give the… →