UTC vs local time: which should you use?
UTC is a single, global reference clock. Local time is what your watch on the wall says, adjusted for your time zone and (often) for daylight saving. They describe the same instant from two different angles: UTC is for computers and coordination, local time is for humans and habits.
What "local time" actually means
Local time is the reading on a clock in a specific place. It's a combination of
the place's time zone (e.g. Europe/London) and the
current UTC offset (e.g. UTC+0 or UTC+1). The offset can change with
the seasons because of daylight saving, with politics (some countries
permanently change their offset), and even with rare leap seconds.
That makes local time inherently unstable. A meeting "next Sunday at 02:30" might be ambiguous (during the autumn DST rollback, that hour happens twice) or non-existent (during the spring forward, that hour is skipped). Local time is fine for end users; it's a nightmare for storage.
What UTC actually means
UTC is a continuous count of seconds, anchored to atomic clocks. It does not observe daylight saving, does not pause, and does not depend on geography. Every networked computer, every cloud database, every phone app stores time in UTC under the hood. When you read a tweet posted "2 minutes ago", the system is comparing your current UTC time to the tweet's UTC timestamp, then converting the difference into a human-readable phrase in your locale.
When to use UTC
- Logs and metrics. Servers around the world produce timestamps; you need a single coordinate to compare them.
- Database storage. Save times as UTC (
TIMESTAMP WITH TIME ZONEor equivalent) so they don't drift if the server moves region. - API contracts. ISO 8601 with a trailing Z (
2026-04-27T14:00:00Z) is unambiguous for any client. - Scheduled jobs. Cron in UTC. Otherwise twice a year your 02:30 job runs zero times or twice.
- Coordination across teams. "The release goes out at 14:00 UTC" is unambiguous; "the release goes out at 2 PM" is not.
When to use local time
- Anything a human reads. "Your booking is at 17:30 in your local time" beats "your booking is at 21:30 UTC" every time.
- Calendar invites. Send the meeting in the host's local time zone; the calendar tool will translate for each invitee.
- Recurring events that follow a person. "Stand-up at 09:00 every weekday" should follow the person across DST — that's a local-time concept.
- UI strings. "Posted 5 minutes ago", "Tomorrow at 3 PM" — always derived from UTC but rendered in the user's locale.
Storing local time without losing information
Sometimes you genuinely need to remember a local-time intent: "the wedding
starts at 16:00 local time in Paris on 2026-06-12, regardless of any future
DST law changes". For these cases, store both the local clock value
and the IANA zone (Europe/Paris). Then re-derive the UTC
timestamp at run time from the latest IANA database. This pattern is sometimes
called "floating time with a zone".
Common pitfalls
- Storing only "20:00" with no zone. You'll never know whether that's UK summer time or US Pacific Standard Time later.
- Hard-coding offsets. Code that says "add 8 hours for China" only works because China happens not to have DST. Most zones do, and your code will silently break in March.
- Treating UTC as English time. UTC is not Western Europe and not Britain. It's a global coordinate that happens to coincide with London winter time.
- Mixing offsets. ISO 8601 lets you write
2026-04-27T14:00:00+01:00; this is unambiguous. Just remember the offset is a snapshot, not the zone.
FAQ
Should I store dates as UTC or local time?
UTC, almost always. The exceptions (recurring local events, scheduled events tied to a wall clock) need both UTC and a zone, not just one or the other.
Is UTC affected by daylight saving?
No. UTC never shifts. Local time shifts; the difference between UTC and local is what "moves".
Why does my browser sometimes show UTC and sometimes local?
Most date APIs default to local time. Functions like Date.prototype.toISOString() in JavaScript return UTC; toLocaleString() returns local. Check the function you're calling.