Yaroslav
Yaroslav

Reputation: 427

TypeError: cant compare offset-naive and offset-aware datetimes

I get datetime object from email message and then I try to compare it with datetime.now().

And then I see this error:

datetime.now() > datetime.strptime('Fri, 31 Jan 2020 09:59:34 +0000 (UTC)', "%a, %d %b %Y %H:%M:%S %z (%Z)"

TypeError: can't compare offset-naive and offset-aware datetimes

How to solve it?

Upvotes: 26

Views: 54179

Answers (5)

Matt
Matt

Reputation: 49

naive_dt = datetime.datetime.utcnow()
aware_dt = datetime.datetime.now(datetime.timezone.utc)

You can also (ab)use the isoformat() and fromisoformat() to add your own offset:

aware_dt = datetime.datetime.fromisoformat(datetime.datetime.now().isoformat()+'+20:00')

Upvotes: 1

WildSiphon
WildSiphon

Reputation: 140

As said in the datetime documentation, date and time objects are categorized as “aware” or “naive” depending on whether or not they include time zone information.

To update your datetime.datetime.now() from naive to aware you can use datetime.timezone.utc.

I also recommend you to use dateutil.parser to parse your generic date/time string to a datetime.datetime object.

Here an example of what you could do:

from datetime import datetime, timezone
from dateutil import parser

datetime.now(timezone.utc) > parser.parse('Fri, 31 Jan 2020 09:59:34 +0000 (UTC)')

See the datetime.timezone documentation and the dateutil.parser documentation for more information.

Upvotes: 10

optimists
optimists

Reputation: 201

You can do like below

print(datetime.today().timestamp() < object.datetime.timestamp())

or

object.datetime.timestamp()) > datetime.today().timestamp()

Upvotes: 5

Brendan Flynn
Brendan Flynn

Reputation: 133

This will happen any time you compare an offset-naive (datetime.now() No Timezone info) to an offset-aware (UTC) time. Python has poor timezone support by default. Even if you used datetime.utcnow() to compare this technically just returns you the UTC time but still has a naive timezone.

My suggestion is to install the pytz package and do:

import pytz

datetime.now().replace(tzinfo=pytz.UTC) > \
    datetime.strptime('Fri, 31 Jan 2020 09:59:34 +0000 (UTC)',
                      "%a, %d %b %Y %H:%M:%S %z (%Z)")

For further reference see: https://docs.python.org/3/library/datetime.html#datetime.datetime.utcnow

Upvotes: 8

macetw
macetw

Reputation: 1840

In many cases, you don't want to have to convert any time zone information. To prevent this, just convert the datetime objects to floats on both sides of the comparator. Use the datetime.timestamp() function.

I also suggest you simplify your date parsing with dateutil.parser.parse(). It's easier to read.

In your example, you might compare your datas like this:

compare_date = 'Fri, 31 Jan 2020 09:59:34 +0000 (UTC)'
datetime.now().timestamp() > parse(compare_date).timestamp()

Upvotes: 32

Related Questions