Search code examples
datetimetimestampunix-timestamppython-datetimetimezone-offset

Understanding Unix Timestamps and Time Zone Conversion in Python


I'm having trouble understanding Unix timestamps and time zone conversions in Python. I have a UTC datetime string ('2023-09-20T05:04:54') and latitude/longitude coordinates (around Toronto). I need to convert this UTC time to local time and obtain Unix timestamps for both, expecting a 4-hour time difference between UTC and Toronto time. However, both timestamps appear the same.

# The input time and lat/lon
utc = '2023-09-20T05:04:54'
latitude = 43.477361 
longitude = -80.513589

# Find the time zone according to lat/lon
tf = TimezoneFinder()
local_timezone = tf.timezone_at(lng=longitude, lat=latitude)
local_timezone = ZoneInfo(local_timezone)  # Convert string to timezone object

# Make sure the input time (utc) is recognized as UTC time by Python
utc_time = datetime.strptime(utc, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc)

# Convert to local time ('America/Toronto')
local_time = utc_time.replace(tzinfo=timezone.utc).astimezone(local_timezone)

# Print Unix timestamps
local_time.timestamp()
#Out[158]: 1695186294.0
utc_time.timestamp()
#Out[159]: 1695186294.0

The time offset between UTC and the Toronto time zone should be -4 hours. However, the Unix timestamps for UTC and Toronto time are the same. Can someone explain why there is no 4-hour difference in the timestamps?


Solution

  • The datetime.timestamp() method returns a unix timestamp. A unix timestamp is number of seconds since Jan 1, 1970 UTC. Hence, regardless of the time zone, it will always return the same time, since they're both the same number of seconds from the 'epoch time' of Jan 1, 1970 UTC

    You can always calculate the time offset from 2 timezones using the pytz library:

    from pytz import timezone
    import pandas as pd
    
    def tz_diff(date, tz1, tz2):
        '''
        Returns the difference in hours between timezone1 and timezone2
        for a given date.
        '''
        date = pd.to_datetime(date)
        return (tz1.localize(date) - 
                tz2.localize(date).astimezone(tz1))\
                .seconds/3600