Time Zones: A Survival Guide for Weary Developers
Everything you need to know about time zones, daylight saving time, and handling dates across the world.
My Nightmare Time Zone Bug (You're Not Alone)
Let me set the scene: It's 3 PM on a Friday, I'm about to head out for the weekend, and I get a panicked message from support: "All our Australian users are seeing yesterday's data!"
I pull up the logs and there it is: We were taking the user's local time, treating it as UTC, and subtracting a day. When it's Saturday morning in Sydney, it's still Friday afternoon in New York. Our code was running on New York servers, and we made the classic mistake of confusing local and UTC.
We fixed it, I missed my weekend plans, and I learned a valuable lesson: Time zones are not something you want to learn by fire.
The good news is: With a few simple rules, you can avoid 99% of time zone bugs. And our Timezone Converter can help you visualize how times translate across the world!
UTC: Your New Best Friend (The Only Safe Time Zone)
Here's rule #1 and it's non-negotiable: Store all times in UTC. Always. No exceptions.
UTC (Coordinated Universal Time) is the time at 0 degrees longitude, and it doesn't have daylight saving time. It's the universal reference point that everything else is relative to.
Let me repeat: Store your database timestamps in UTC. Store your API timestamps in UTC. Store your log timestamps in UTC. Just use UTC for everything that's not directly being shown to a user.
If you take only one thing away from this guide, let it be this: UTC is the safe choice. I've seen so many bugs from storing local time, and I've never seen a bug from storing UTC.
When you need to show the time to a user, convert from UTC to their time zone at the last possible moment. Frontend can handle this, or your API can handle it if you know the user's time zone.
The Time Zone Database (And Why It Matters)
You might have seen time zone identifiers like these:
- `America/New_York`
- `Europe/London`
- `Asia/Tokyo`
- `Australia/Sydney`
These are from the IANA Time Zone Database (often called tzdb or zoneinfo), and it's the source of truth for time zones.
It's not just a list of offsets — it contains the history of time zone changes, daylight saving time rules, and even historical oddities like places skipping a day when they switched sides of the International Date Line!
Here's why this matters: You can't just use fixed offsets like UTC-5 for New York. New York uses UTC-5 in winter (EST) and UTC-4 in summer (EDT). The database knows when these switches happen.
Always use these identifiers, never fixed offsets, when storing user time zone preferences!
Daylight Saving Time: The Human-Made Disaster
Daylight saving time (DST) is the practice of setting clocks forward an hour in spring and back an hour in autumn. It's confusing, unnecessary, and a constant source of bugs.
Here's what makes it hard:
- The dates change! Countries change the start/end dates of DST. Sometimes with very little notice!
- Not all places observe it. Arizona doesn't, Hawaii doesn't, most of Asia doesn't.
- When clocks spring forward, there's a missing hour (e.g., 2 AM becomes 3 AM). When clocks fall back, there's a repeated hour (e.g., 2 AM happens twice).
I once had a bug where a job scheduled at 2:30 AM didn't run on the day DST started, and ran twice on the day DST ended. Fun!
The good news is: Good time zone libraries handle this for you. Another reason to never roll your own!
Common Time Zone Patterns in Production
Here are patterns I've seen work well in real systems:
**Pattern 1: UTC everywhere, convert at the edge**
- Database: UTC timestamps
- Backend: Works only in UTC
- API: Returns ISO 8601 with Z (UTC)
- Frontend: Converts to user's local time for display
This is the simplest and most robust pattern, and what I recommend for most apps.
**Pattern 2: Store user's time zone preference**
- If you have user accounts, let them select their time zone (from the IANA list!)
- Store their preference alongside other user settings
- When sending emails or scheduled notifications, use their preferred time zone
**Pattern 3: Future events are tricky**
- If you have an event like "June 20 at 2 PM local time", you need to store the local time and the time zone separately from a UTC timestamp! Because the UTC offset might change before the event happens!
- This is an advanced topic, but it's important to know about for calendars and scheduling apps.
Our Timezone Converter can help you experiment with how the same moment looks across different parts of the world.
Time Zone Tools You Should Know About
Here are my go-to tools for working with time zones:
**First, our tools (of course!):**
- Timezone Converter — See the same moment across multiple time zones
- Timestamp Converter — Convert between timestamps and human-readable times
- Date Formatter — Format dates in different time zones
**Other useful tools:**
- `time.is` — Quick check of what time it is anywhere in the world
- `timeanddate.com` — Great for researching time zone history
- `World Time Buddy` — Side-by-side comparisons (good for scheduling meetings!)
**In code:**
- JavaScript: `Intl.DateTimeFormat` with timeZone option, or luxon
- Python: `pytz` or `zoneinfo` (Python 3.9+)
- Database: PostgreSQL has excellent time zone support with `TIMESTAMP WITH TIME ZONE`
Remember: The goal isn't to memorize all time zones — it's to have good patterns and tools to handle them without bugs!
Try These Tools
Open the tools that go with this tutorial and practice what you learned.
Timezone Converter
Convert times between different timezones around the world.
Timestamp Converter
Convert between UNIX timestamps, ISO 8601, and human-readable dates.
Date Formatter
Format dates and times in various formats including ISO, RFC, and custom patterns.
More Tutorials in This Category
Keep Learning
Date Formatting: A Complete Guide for Developers
Learn how to format dates and times for APIs, user interfaces, and databases with real-world examples.
Date Calculations: Adding Days, Calculating Differences, and More
Learn how to calculate differences between dates, add/subtract time, and handle edge cases.