On , I learnt ...
To prefer dateutil
over pytz
When constructing datetime.datetime
instances, it’s better to use dateutil
to provide the tzinfo
argument — avoid using pytz
.
That is, prefer this:
import datetime
from dateutil import tz
tzinfo = tz.gettz("Europe/London")
datetime.datetime(2021, 10, 30, 12, 0, tzinfo=tzinfo)
to
import datetime
import pytz
tzinfo = pytz.timezone("Europe/London")
datetime.datetime(2021, 10, 30, 12, 0, tzinfo=tzinfo)
Why? Because passing pytz
’s timezones to the datetime.datetime
constructor
can often lead to bugs after date arithmetic (i.e. computing new dates using
datetime.timedelta
). This is noted in the
pytz
docs:

It’s easy to be lulled into a false sense of security as such bugs don’t affect timezones without daylight savings transitions, like UTC.
See
pytz
: The Fastest Footgun in the West
for more details.