Introduction
When working with dates, oftentimes, you'd like to know if a given date comes before or after another date. We can get these answers by comparing dates.
In this article, we will learn how to use the Python datetime
module to create and compare both naive (without timezone info) and aware (with timezone info) dates.
To compare the dates, we will use the comparison operators in Python: <, >, ==, <=, >=, !=
.
Note: The datetime
module has two methods for creating dates object - datetime.datetime
and datetime.date
. Comparisons can only be made on objects created from the same class:
datetime.datetime.now() >= datetime.date.today()
This will result in a TypeError
:
TypeError: can't compare datetime.datetime to datetime.date
Comparing Timezone-Naive Datetimes
Let's start off with comparing naive dates, which don't have any timezone information. First, we'll want to import the datetime
module:
from datetime import datetime, date
Then, let's make a few dates that we can compare:
date1 = date(1995, 3, 20)
date2 = date(2020, 1, 1)
dob_a = datetime(1995, 3, 20)
dob_b = datetime(2020, 1, 1)
Comparing these objects is made as easy as comparing, say, integers. A date is less than another, if its time precedes the other.
In our case, date1
is considered less (<
) than date2
because it's farther back in time:
print("date1 comes before date2?", date1 < date2)
print("date1 comes after date2?", date1 > date2)
print("date1 is equal to date2?", date1 == date2)
This results in:
date1 comes before date2? True
date1 comes after date2? False
date1 is equal to date2? False
Now, you'd typically incorporate this logic into some flow-control statements:
if dob_a > dob_b:
print("person a is older than person b")
else:
print("person b is older than person a")
This results in:
person b is older than person a
Comparing Timezone-Aware Datetimes
Time zones can complicate things a bit, though, thankfully, we can apply the exact same logic to the comparison. The only difference is that we're working with aware dates - dates with additional information about the time zone they're in:
from datetime import datetime
import pytz
# Create timezone objects for different parts of the world
tz_ny= pytz.timezone('America/New_York')
tz_lon = pytz.timezone("Europe/London")
# Year, Month, Day, Hour, Minute, Second
datetime = datetime(2010, 4, 20, 23, 30, 0)
# Localize the given date, according to the timezone objects
date_with_timezone_1 = tz_ny.localize(datetime)
date_with_timezone_2 = tz_lon.localize(datetime)
# These are now, effectively no longer the same *date* after being localized
print(date_with_timezone_1) # 2010-04-20 23:30:00-04:00
print(date_with_timezone_2) # 2010-04-20 23:30:00+01:00
print(date_with_timezone_1 == date_with_timezone_2)
Running this code results in:
False
While this statement:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
print(date_with_timezone_1 > date_with_timezone_2)
Would result in:
True
Now, this result might strike you as a bit odd. We're comparing these two datetimes:
2010-04-20 23:30:00-04:00 # date_with_timezone_1
2010-04-20 23:30:00+01:00 # date_with_timezone_2
Intuitively, it looks like date_with_timezone_2
is indeed larger than date_with_timezone_1
. Though, let's take a look at how the localize()
function works.
Here, we've used the pytz
library to make our naive dates aware. We've constructed a timezone object for New York (tz_ny
), and a timezone object for London (tz_lon
).
Then, to inject timezone information into our datetime
object, we've run the localize()
function and packed the result into date_with_timezone_1
and date_with_timezone_2
.
We've put in 11:30PM into localize()
, which in turn created a datetime for 11:30PM in New York, and 11:30PM in London respectively. To get from 11:30PM in New York, to 11:30PM in London, you'd have to add 4 hours. More time has passed to get New York to 11:30PM, than it took to get London to 11:30PM. Thus, the datetime corresponding to New York at 11:30PM is larger than the datetime corresponding to London at 11:30PM.
Please keep this behavior in mind when working with timezones this way.
However, it is worthy of note that comparing aware dates with naive dates will result in an error:
date_with_timezone = tz_ny.localize(datetime)
print(datetime == date_without_timezone)
This will result in the following error:
TypeError: can't compare offset-naive and offset-aware datetimes
So to compare datetime objects, both objects must both be either naive or aware.
Conclusion
In this article, we have discussed ways of comparing both timezone-aware and timezone-naive dates in Python, we have also looked at possible pitfalls that we may encounter when comparing dates and possible workarounds.
If you have any questions or contributions please leave them in the comments section below.