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
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()
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149)
>>> now1_uk = uk.localize(now1)
datetime.datetime(2015, 6, 1, 11, 53, 50, 15149, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now1_utc = now1_uk.astimezone(utc)
datetime.datetime(2015, 6, 1, 10, 53, 50, 15149, tzinfo=)
>>> now2 = datetime.today()
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862)
>>> now2_uk = uk.localize(now2)
datetime.datetime(2015, 6, 1, 11, 56, 3, 22862, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)
>>> now2_utc = now2_uk.astimezone(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/