Python: Timezone and Daylight savings

Timezone is a hard problem. DST is even a harder problem. I found myself walking into problems and problems when I started using datetime in Python properly. So I decide to write a blog to share my experience.

“Naive” and “Aware”

The first thing to know is that in Python there are two types of datetime: offset-naive and offset-aware. Offset naive means that the datetime has no timezone information. It could be very error prone if you are new to Python. If you mix a naive datetime and aware datetime, you will get an error. And Python does not have built-in timezone support, you need to use pytz, a module for timezone information.

import pytz
from datetime import datetime
tznaive_datetime = datetime(2018, 1, 1, 12, 0)
tzaware_datetime = datetime(2018, 1, 1, 12, 0, tzinfo=pytz.utc)
# this will raise an error
tznaive_datetime == tzaware_datetime
import datetime
import pytz
import tzlocal
def utcnow():
return pytz.utc.localize(datetime.utcnow())
def now():
return tzlocal.get_localzone().localize(
>>> from datetime import datetime
>>> datetime.strptime('2017-11-15T12:00:00-0700', '%Y-%m-%dT%H:%M:%S%z')
ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%m:%S%z'
>>> from dateutil import parser
>>> parser.parse('2017-11-15T12:00:00-07')
datetime.datetime(2017, 11, 15, 12, 0, tzinfo=tzoffset(None, -25200))
>>> import pytz
>>> pst = pytz.timezone("US/Pacific")
>>> pst.localize(datetime(2017, 10, 1)).dst()
datetime.timedelta(0, 3600)
>>> pst.localize(datetime(2017, 12, 1)).dst()
>>> (pst.localize(datetime(2017, 10, 1)) + timedelta(days=60)).dst()
datetime.timedelta(0, 3600)
pst.localize(yourdate.replace(tzinfo=None) + td).dst()

Written by

I write, so I learn.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store