Tuesday, October 27, 2020

The curious case of Python's datetime -0753 UTC offset

 "Time, the devourer of all things." - Ovid's Metamorphoses

Confused why your python datetime object's UTC offset is showing up as -0753 instead of -0700 (PDT) or -0800 (PST)? I certainly was.

The tl;dr is because Python's pytz does not do the right thing with daylight saving's time when simply adding a timezone to a naive datetime object, and you must localize it.

Here's an example of what I was encountering. I was parsing a timestamp which was in the America/Los_Angeles timezone. I needed to change the printed format, so I parsed the date and did a quick strftime and... -0753??

from datetime import datetime
import pytz

tz = pytz.timezone("America/Los_Angeles")

# Super duper sure this is America/Los_Angeles tz
niave_string = "2020-10-05 14:03:40"

dateobj = datetime.strptime(niave_string, "%Y-%m-%d %H:%M:%S")

# Make it a timezone-aware object (Or so you think)
dateobj = dateobj.replace(tzinfo=tz)

# Notice the -0753 UTC offset...
print(dateobj.strftime("%Y-%m-%d %H:%M:%S%z"))

'2020-10-05 14:03:40-0753'

The mismatch happens because you can't just slap a tz onto a naive datetime object and hope it will do the right thing. More info on what's happening here can be found on this great stack overflow answer.

The fix for this is to localize your date objects, not just replace the TZ:

from datetime import datetime
import pytz

tz = pytz.timezone("America/Los_Angeles")

# Super duper sure this is America/Los_Angeles tz
niave_string = "2020-10-05 14:03:40"

dateobj = datetime.strptime(niave_string, "%Y-%m-%d %H:%M:%S")

# Localize your date object to your timezone
dateobj = tz.localize(dateobj)

# 🤞🏻
print(dateobj.strftime("%Y-%m-%d %H:%M:%S%z"))

'2020-10-05 14:03:40-0700'

Much better.

No comments:

Post a Comment