Building a Time Zone Converter: The Developer's Guide
Time zone conversion looks simple: look up the offset, add or subtract. But DST rules change frequently, half-hour zones exist, and historical conversions require knowing what the rules were at that moment. The IANA Time Zone Database is updated 3-4 times per year with rule changes, and each change can affect conversions going back decades.
If your application needs to convert "March 9, 2025, 2:30 AM" from New York to London, you need to know that DST started in the US on March 9 that year — so 2:30 AM does not exist (clocks jumped from 2:00 to 3:00). Getting this wrong means your user misses a meeting.
API Options Compared
WorldTimeAPI (free, no auth): Simple REST API. GET /api/timezone/{area}/{location} returns current time and offset. Good for current-time lookups. Rate limited.
TimeZoneDB (freemium): REST API with timezone conversion, DST info, and zone listing. Free tier: 1 request/second.
Google Time Zone API: Requires Google Cloud account (free tier: $200/month credit). Returns offset for a location + timestamp. Does not return IANA zone name.
Abstract API Time Zone: Clean REST API with current time, conversion, and location lookup. Free tier: 1 request/second, 500 requests/day.
Self-hosted (recommended for scale): Use the IANA database directly via language libraries. No API limits, no network latency, works offline. Requires updating when rules change.
Implementation: The Right Way
The pattern that works in production:
- Accept input as IANA zone name + local datetime. Never accept "EST" or "GMT+5"
- Convert to UTC immediately. Store and transmit UTC internally.
- Convert to target zone at display time. Use the rules for that specific datetime.
- Handle ambiguous/non-existent times explicitly.
Example in Python (using zoneinfo, stdlib since 3.9):
from zoneinfo import ZoneInfo
from datetime import datetime
# Convert 3 PM New York time to Tokyo time
ny_time = datetime(2026, 6, 15, 15, 0, tzinfo=ZoneInfo("America/New_York"))
tokyo_time = ny_time.astimezone(ZoneInfo("Asia/Tokyo"))
print(tokyo_time) # 2026-06-16 04:00:00+09:00
Common Pitfalls
Pitfall 1: Using the current offset for future dates. DST rules may change between now and the date you are converting.
Pitfall 2: Ignoring the "gap" in spring-forward. If a user enters 2:30 AM on the day clocks spring forward, that time does not exist.
Pitfall 3: Ignoring the "overlap" in fall-back. 1:30 AM happens twice. If you do not specify which occurrence, you may be off by an hour.
Pitfall 4: Not updating the tz database. Subscribe to the IANA tz-announce mailing list.
FAQ
What is the best free time zone API?
WorldTimeAPI is simplest for current-time lookups. Abstract API or TimeZoneDB work for conversions. For production, self-hosting the IANA database is the most reliable option.
How often do time zone rules change?
The IANA Time Zone Database releases updates 3-4 times per year. Major changes (a country switching zones) happen roughly once per year.
Can I use Google Sheets for time zone conversion?
Google Sheets has limited native time zone support. For reliable results across DST transitions, a proper library or API is recommended.