How to Convert Between Time Zones
Time zone conversion breaks in two ways: getting the offset wrong, and ignoring daylight saving time. New York is UTC−5 in winter and UTC−4 in summer. "5 PM EST" in February uses a different UTC offset than "5 PM EDT" in July. Tools and code that hardcode offsets get this wrong.
In the browser
Enter a time and pick two zones in the Time Zone Converter to see the equivalent. The converter uses IANA timezone data, so DST transitions are handled automatically — no manual offset adjustment needed.
UTC offsets for common time zones
| City | IANA zone | Standard offset | DST offset |
|---|---|---|---|
| New York | America/New_York | UTC−5 | UTC−4 |
| London | Europe/London | UTC+0 | UTC+1 |
| Paris | Europe/Paris | UTC+1 | UTC+2 |
| Dubai | Asia/Dubai | UTC+4 | — (no DST) |
| Mumbai | Asia/Kolkata | UTC+5:30 | — (no DST) |
| Singapore | Asia/Singapore | UTC+8 | — (no DST) |
| Tokyo | Asia/Tokyo | UTC+9 | — (no DST) |
| Sydney | Australia/Sydney | UTC+10 | UTC+11 |
Use IANA zone names (America/New_York) rather than abbreviations (EST). EST is ambiguous — it refers to different zones in North America and Australia.
Python
Python 3.9+ includes zoneinfo in the standard library. No third-party packages needed.
from datetime import datetime
from zoneinfo import ZoneInfo
# Create a timezone-aware datetime
ny_time = datetime(2026, 3, 15, 14, 30, tzinfo=ZoneInfo('America/New_York'))
# Convert to other zones
london = ny_time.astimezone(ZoneInfo('Europe/London'))
tokyo = ny_time.astimezone(ZoneInfo('Asia/Tokyo'))
print(f'New York: {ny_time:%Y-%m-%d %H:%M %Z}')
print(f'London: {london:%Y-%m-%d %H:%M %Z}')
print(f'Tokyo: {tokyo:%Y-%m-%d %H:%M %Z}')
# Convert the current UTC time to multiple zones
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
now_utc = datetime.now(timezone.utc)
zones = ['America/New_York', 'Europe/London', 'Asia/Singapore', 'Asia/Tokyo']
for tz in zones:
local = now_utc.astimezone(ZoneInfo(tz))
print(f'{tz:<25} {local:%Y-%m-%d %H:%M %Z}')
JavaScript
// Convert a date to a specific timezone
function convertToTimezone(date, timezone) {
return new Intl.DateTimeFormat('en-CA', {
timeZone: timezone,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false,
}).format(date);
}
const now = new Date();
console.log(convertToTimezone(now, 'America/New_York'));
console.log(convertToTimezone(now, 'Asia/Tokyo'));
console.log(convertToTimezone(now, 'Europe/London'));
// Get the current UTC offset (in minutes) for any timezone
function getUtcOffsetMinutes(timezone, date = new Date()) {
const utc = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
const tz = new Date(date.toLocaleString('en-US', { timeZone: timezone }));
return (tz - utc) / 60000;
}
console.log(getUtcOffsetMinutes('America/New_York')); // -300 or -240 depending on DST
console.log(getUtcOffsetMinutes('Asia/Tokyo')); // always 540
The naive datetime trap
A Python datetime without timezone info is naive — it has no concept of DST. Arithmetic on naive datetimes produces wrong results across DST transitions.
from datetime import datetime, timedelta
# Wrong — naive datetime on US DST changeover day (clocks spring forward at 2 AM)
dt = datetime(2026, 3, 8, 1, 0)
print(dt + timedelta(hours=2)) # Shows 3:00 AM, but local time jumped to 3 AM at 2 AM
# Correct — aware datetime
from zoneinfo import ZoneInfo
dt = datetime(2026, 3, 8, 1, 0, tzinfo=ZoneInfo('America/New_York'))
print(dt + timedelta(hours=2)) # Correctly accounts for the DST gap
Always attach a timezone when creating a datetime you'll do arithmetic on.
Storing and transmitting times
| Approach | Problem |
|---|---|
Store as EST / PST |
Ambiguous abbreviation, DST not encoded |
Store as UTC offset (-05:00) |
Doesn't encode future DST behavior |
| Store as UTC + IANA zone name | Correct — unambiguous, DST handled |
For databases: store the UTC timestamp. Store the IANA zone name separately if you need to display local time. Reconstruct local time at read time.
Key takeaways
- Use IANA zone names (
America/New_York) — abbreviations likeESTare ambiguous across continents. - Python 3.9+
zoneinfohandles DST automatically; no need forpytzon modern projects. - Naive datetimes produce wrong results across DST boundaries — always attach a timezone.
- Dubai, Mumbai, Singapore, and Tokyo have no DST — their offset is constant year-round.
- Store timestamps as UTC in databases; reconstruct local time with the IANA zone name at display time.