🌍 Handling Timezones

Working with timezones is essential for global applications. Python provides robust timezone support through the zoneinfo module (Python 3.9+) and datetime module, allowing you to create timezone-aware datetime objects and convert between different timezones.

from datetime import datetime
from zoneinfo import ZoneInfo

# Create timezone-aware datetimes
utc_time = datetime.now(ZoneInfo("UTC"))
ny_time = datetime.now(ZoneInfo("America/New_York"))
tokyo_time = datetime.now(ZoneInfo("Asia/Tokyo"))

print(f"UTC: {utc_time}")
print(f"New York: {ny_time}")
print(f"Tokyo: {tokyo_time}")

# Convert between timezones
ny_to_tokyo = ny_time.astimezone(ZoneInfo("Asia/Tokyo"))
print(f"NY time in Tokyo: {ny_to_tokyo}")

🎯 Understanding Timezone-Aware Datetimes

Python datetime objects can be either naive (no timezone) or aware (with timezone information).

Creating Timezone-Aware Datetimes

from datetime import datetime
from zoneinfo import ZoneInfo

# Current time in different timezones
utc_now = datetime.now(ZoneInfo("UTC"))
eastern = datetime.now(ZoneInfo("America/New_York"))
pacific = datetime.now(ZoneInfo("America/Los_Angeles"))
london = datetime.now(ZoneInfo("Europe/London"))

print(f"UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
print(f"Eastern: {eastern.strftime('%Y-%m-%d %H:%M:%S %Z')}")
print(f"Pacific: {pacific.strftime('%Y-%m-%d %H:%M:%S %Z')}")
print(f"London: {london.strftime('%Y-%m-%d %H:%M:%S %Z')}")

Converting Between Timezones

from datetime import datetime
from zoneinfo import ZoneInfo

# Start with UTC time
utc_time = datetime.now(ZoneInfo("UTC"))
print(f"UTC time: {utc_time.strftime('%H:%M:%S %Z')}")

# Convert to different timezones
timezones = [
    "America/New_York",
    "America/Los_Angeles", 
    "Europe/London",
    "Asia/Tokyo",
    "Australia/Sydney"
]

for tz_name in timezones:
    local_time = utc_time.astimezone(ZoneInfo(tz_name))
    print(f"{tz_name}: {local_time.strftime('%H:%M:%S %Z')}")

Working with Specific Dates

from datetime import datetime
from zoneinfo import ZoneInfo

# Create specific datetime with timezone
meeting_utc = datetime(2024, 3, 15, 14, 30, tzinfo=ZoneInfo("UTC"))
print(f"Meeting in UTC: {meeting_utc}")

# Show meeting time in different locations
locations = {
    "New York": "America/New_York",
    "Los Angeles": "America/Los_Angeles",
    "London": "Europe/London",
    "Tokyo": "Asia/Tokyo",
    "Sydney": "Australia/Sydney"
}

print("Meeting times around the world:")
for city, tz_name in locations.items():
    local_time = meeting_utc.astimezone(ZoneInfo(tz_name))
    formatted = local_time.strftime('%I:%M %p on %B %d')
    print(f"  {city}: {formatted}")

🔄 Timezone Conversion Utilities

Practical functions for timezone operations.

Timezone Converter

from datetime import datetime
from zoneinfo import ZoneInfo

def convert_timezone(dt, from_tz, to_tz):
    """Convert datetime from one timezone to another"""
    if dt.tzinfo is None:
        # If naive, assume it's in from_tz
        dt = dt.replace(tzinfo=ZoneInfo(from_tz))
    else:
        # If aware, convert to from_tz first if needed
        dt = dt.astimezone(ZoneInfo(from_tz))
    
    return dt.astimezone(ZoneInfo(to_tz))

def format_time_in_zones(dt, zones):
    """Format datetime in multiple timezones"""
    results = []
    for zone_name in zones:
        local_time = dt.astimezone(ZoneInfo(zone_name))
        formatted = local_time.strftime('%Y-%m-%d %H:%M %Z')
        results.append(f"{zone_name}: {formatted}")
    return results

# Example usage
base_time = datetime(2024, 3, 15, 10, 30, tzinfo=ZoneInfo("America/New_York"))

zones = ["UTC", "America/Los_Angeles", "Europe/London", "Asia/Tokyo"]
for line in format_time_in_zones(base_time, zones):
    print(line)

Business Hours Checker

from datetime import datetime, time
from zoneinfo import ZoneInfo

def is_business_hours(dt, timezone_name, 
                     start_hour=9, end_hour=17, 
                     business_days=range(0, 5)):
    """Check if datetime falls within business hours"""
    # Convert to local timezone
    local_dt = dt.astimezone(ZoneInfo(timezone_name))
    
    # Check if it's a business day (Monday=0, Sunday=6)
    if local_dt.weekday() not in business_days:
        return False
    
    # Check if it's during business hours
    business_start = time(start_hour, 0)
    business_end = time(end_hour, 0)
    current_time = local_dt.time()
    
    return business_start <= current_time <= business_end

# Example usage
test_time = datetime(2024, 3, 15, 14, 30, tzinfo=ZoneInfo("UTC"))  # Friday 2:30 PM UTC

locations = [
    ("New York", "America/New_York"),
    ("Los Angeles", "America/Los_Angeles"),
    ("London", "Europe/London"),
    ("Tokyo", "Asia/Tokyo")
]

for city, tz in locations:
    local_time = test_time.astimezone(ZoneInfo(tz))
    is_open = is_business_hours(test_time, tz)
    status = "OPEN" if is_open else "CLOSED"
    print(f"{city}: {local_time.strftime('%H:%M %A')} - {status}")

Meeting Scheduler

from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

def find_good_meeting_time(start_date, participants_timezones, 
                          preferred_hours=range(9, 17)):
    """Find meeting times that work for multiple timezones"""
    good_times = []
    
    # Check each hour over several days
    for day_offset in range(7):  # Check next 7 days
        current_date = start_date + timedelta(days=day_offset)
        
        # Skip weekends
        if current_date.weekday() >= 5:
            continue
            
        for hour in range(24):
            utc_time = datetime(current_date.year, current_date.month, 
                              current_date.day, hour, 0, 
                              tzinfo=ZoneInfo("UTC"))
            
            # Check if this time works for all participants
            works_for_all = True
            time_details = []
            
            for participant_tz in participants_timezones:
                local_time = utc_time.astimezone(ZoneInfo(participant_tz))
                local_hour = local_time.hour
                
                if (local_hour not in preferred_hours or 
                    local_time.weekday() >= 5):
                    works_for_all = False
                    break
                
                time_details.append(f"{participant_tz}: {local_time.strftime('%H:%M')}")
            
            if works_for_all:
                good_times.append({
                    'utc_time': utc_time,
                    'details': time_details
                })
    
    return good_times[:5]  # Return first 5 good options

# Example usage
participants = [
    "America/New_York",
    "Europe/London", 
    "Asia/Tokyo"
]

start_search = datetime(2024, 3, 18, tzinfo=ZoneInfo("UTC"))  # Start Monday
good_meetings = find_good_meeting_time(start_search, participants)

print("Good meeting times for all participants:")
for i, meeting in enumerate(good_meetings, 1):
    print(f"\nOption {i}: {meeting['utc_time'].strftime('%A, %B %d at %H:%M UTC')}")
    for detail in meeting['details']:
        print(f"  {detail}")

📊 Common Timezone Reference

Major Timezone Identifiers

RegionTimezone IdentifierUTC Offset (Standard)
Americas
New YorkAmerica/New_YorkUTC-5 (UTC-4 DST)
Los AngelesAmerica/Los_AngelesUTC-8 (UTC-7 DST)
ChicagoAmerica/ChicagoUTC-6 (UTC-5 DST)
TorontoAmerica/TorontoUTC-5 (UTC-4 DST)
Europe
LondonEurope/LondonUTC+0 (UTC+1 DST)
ParisEurope/ParisUTC+1 (UTC+2 DST)
BerlinEurope/BerlinUTC+1 (UTC+2 DST)
MoscowEurope/MoscowUTC+3
Asia
TokyoAsia/TokyoUTC+9
ShanghaiAsia/ShanghaiUTC+8
MumbaiAsia/KolkataUTC+5:30
DubaiAsia/DubaiUTC+4
Oceania
SydneyAustralia/SydneyUTC+10 (UTC+11 DST)
AucklandPacific/AucklandUTC+12 (UTC+13 DST)

UTC Operations

from datetime import datetime
from zoneinfo import ZoneInfo

def to_utc(dt, source_timezone=None):
    """Convert any datetime to UTC"""
    if dt.tzinfo is None and source_timezone:
        # Make naive datetime timezone-aware
        dt = dt.replace(tzinfo=ZoneInfo(source_timezone))
    
    if dt.tzinfo is None:
        raise ValueError("Cannot convert naive datetime without source timezone")
    
    return dt.astimezone(ZoneInfo("UTC"))

def from_utc(utc_dt, target_timezone):
    """Convert UTC datetime to target timezone"""
    if utc_dt.tzinfo is None:
        utc_dt = utc_dt.replace(tzinfo=ZoneInfo("UTC"))
    
    return utc_dt.astimezone(ZoneInfo(target_timezone))

# Example usage
local_time = datetime(2024, 3, 15, 14, 30)  # Naive datetime
utc_time = to_utc(local_time, "America/New_York")
tokyo_time = from_utc(utc_time, "Asia/Tokyo")

print(f"Local (NY): {local_time}")
print(f"UTC: {utc_time}")
print(f"Tokyo: {tokyo_time}")

🎯 Key Takeaways

🚀 What's Next?

Now that you can handle timezones, learn how to work with Unix timestamps for system integration.

Continue to: Work with Timestamps

Was this helpful?

😔Poor
🙁Fair
😊Good
😄Great
🤩Excellent