Trying to write a test to see if my datetime
conversions are working appropriately and getting some unexpected results.
import pytz
from datetime import datetime
def format_datetime(dt):
if not dt.tzinfo:
raise pytz.UnknownTimeZoneError('timezone not set')
time = dt.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%S')
millis = dt.microsecond / 1000
string = '{}{}'.format(time, '.%03dZ' % millis)
return string
dt = datetime(2019, 3, 20, 1, 1, 1, 1)
# test 1
utc_dt = dt.replace(tzinfo=pytz.utc)
pdt_dt = dt.replace(tzinfo=pytz.timezone('America/Los_Angeles'))
print(format_datetime(utc_dt)) # 2019-03-20T01:01:01.000Z
print(format_datetime(pdt_dt)) # 2019-03-20T08:54:01.000Z
# test 2
utc_dt2 = dt.replace(tzinfo=pytz.utc)
pdt_dt2 = utc_dt2.astimezone(pytz.timezone('America/Los_Angeles'))
print(format_datetime(utc_dt2)) # 2019-03-20T01:01:01.000Z
print(format_datetime(pdt_dt2)) # 2019-03-20T01:01:01.000Z
I don't understand why, in the first test print(format_datetime(pdt_dt))
changes the minutes value, but in the second test the minutes aren't changed. (I understand why the hours are different between the two examples).
You can't just assign a pytz
timezone to a datetime
, you must use localize
or astimezone
:
utc_dt = pytz.utc.localize(dt)
pdt_dt = utc_dt.astimezone(pytz.timezone('America/Los_Angeles'))
This is because timezones are subject to change, and the pytz
zone objects contain the entire history and need to be configured for the correct time period. A simple replace
doesn't allow for this. Some of those old historic periods will have an odd number of minutes offset.