Comparing Datetimes in Python with and without Timezones

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:

Free eBook: Git Essentials

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.

Last Updated: August 25th, 2021
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Geoffery, JosephAuthor

I am a software developer with interests in open source, android development (with kotlin), backend web development (with python), and data science (with python as well).

Project

Building Your First Convolutional Neural Network With Keras

# python# artificial intelligence# machine learning# tensorflow

Most resources start with pristine datasets, start at importing and finish at validation. There's much more to know. Why was a class predicted? Where was...

David Landup
David Landup
Details
Course

Data Visualization in Python with Matplotlib and Pandas

# python# pandas# matplotlib

Data Visualization in Python with Matplotlib and Pandas is a course designed to take absolute beginners to Pandas and Matplotlib, with basic Python knowledge, and...

David Landup
David Landup
Details

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms