Compare dates in Python when one is timezone aware

I’ve recently started using Python, and the other day I had to compare a stored date with today’s date. I got an error:
TypeError: can't compare offset-naive and offset-aware datetimes

It turns out that the stored date had a timezone (it is timezone-aware) but by default today’s date (datetime.today()) doesn’t (it is timezone-naive).

My stored date looks like this:
datetime.datetime(2015, 3, 26, 17, 10, 1, 257894, tzinfo=<UTC>)
Today’s date like this:
datetime.datetime(2015, 3, 26, 16, 19, 38, 442042)

In order to do a comparison you can either remove the timezone from one, or add it to the other.

Removing timezone information

The simplest option, if you’re sure the dates you are comparing are in the same timezone would be to simply remove the timezone information.

mydate = mydate.replace(tzinfo=None)

Adding timezone information

You can add timezone information to a datetime using the localize method of the pytz library.

from datetime import datetime
import pytz
now = datetime.today())
now_utc = pytz.utc.localize(now)

However, what if your timezone is not UTC? For example when the clocks go forward in the spring in the UK we are on UTC + 1, but in the winter we are back to UTC. Well, you can get the local timezone which is aware of the clocks going forward and back in spring and autumn.

uk = pytz.timezone('Europe/London')
now_uk = uk.localize(now)

It is also possible to convert from one timezone to another.

utc = pytz.utc
<ipdb> now_utc = now_uk.astimezone(utc)

Let’s try this out:
>>> from datetime import datetime
>>> import pytz
>>> uk = pytz.timezone('Europe/London')
>>> utc = pytz.utc
>>> now1 = datetime.today()
>>> now1
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149)
>>> now1_uk = uk.localize(now1)
>>> now1_uk
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now1_utc = now1_uk.astimezone(utc)
>>> now1_utc
datetime.datetime(2015, 6, 1, 10, 53, 50, 15149, tzinfo=)
>>> now2 = datetime.today()
>>> now2
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862)
>>> now2_uk = uk.localize(now2)
>>> now2_uk
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now2_utc = now2_uk.astimezone(utc)
>>> now2_utc
datetime.datetime(2015, 6, 1, 10, 56, 3, 22862, tzinfo=)
>>> now1_uk < now2_uk True >>> now1_uk < now2_utc True >>> now1_utc < now2_uk True >>> now1_utc < now2_utc True >>>

Here we created a datetime now1, and another a few minutes later now2. Then we create a UK and UTC version for each. The older date (now1) is correctly compared with the newer date (now2) in each case, even where the timezones are different.

For more information on using timezones in Python, see http://pytz.sourceforge.net/