All Tools / Blog / How to Convert Between Time Zones

How to Convert Between Time Zones

3 min read

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 like EST are ambiguous across continents.
  • Python 3.9+ zoneinfo handles DST automatically; no need for pytz on 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.