The Python Oracle

Can't compare naive and aware datetime.now() <= challenge.datetime_end

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 3

--

Chapters
00:00 Question
01:03 Accepted answer (Score 277)
01:57 Answer 2 (Score 161)
02:22 Answer 3 (Score 120)
03:02 Answer 4 (Score 50)
03:25 Thank you

--

Full question
https://stackoverflow.com/questions/1530...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #django #datetime #comparison

#avk47



ACCEPTED ANSWER

Score 319


By default, the datetime object is naive in Python, so you need to make both of them either naive or aware datetime objects. This can be done using:

import datetime
import pytz

utc=pytz.UTC

challenge.datetime_start = utc.localize(challenge.datetime_start) 
challenge.datetime_end = utc.localize(challenge.datetime_end) 
# now both the datetime objects are aware, and you can compare them

Note: This would raise a ValueError if tzinfo is already set. If you are not sure about that, just use

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)

BTW, you could format a UNIX timestamp in datetime.datetime object with timezone info as following

d = datetime.datetime.utcfromtimestamp(int(unix_timestamp))
d_with_tz = datetime.datetime(
    year=d.year,
    month=d.month,
    day=d.day,
    hour=d.hour,
    minute=d.minute,
    second=d.second,
    tzinfo=pytz.UTC)



ANSWER 2

Score 171


datetime.datetime.now is not timezone aware.

Django comes with a helper for this, which requires pytz

from django.utils import timezone
now = timezone.now()

You should be able to compare now to challenge.datetime_start




ANSWER 3

Score 136


One line of code solution

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code

Explained version

# Timezone info of your timezone aware variable
timezone = your_timezone_aware_variable.tzinfo

# Current datetime for the timezone of your variable
now_in_timezone = datetime.datetime.now(timezone)

# Now you can do a fair comparison, both datetime variables have the same time zone
if your_timezone_aware_variable <= now_in_timezone:
    pass #some code

Summary

You must add the timezone info to your now() datetime.
However, you must add the same timezone of the reference variable; that is why I first read the tzinfo attribute.




ANSWER 4

Score 59


Disable time zone. Use challenge.datetime_start.replace(tzinfo=None);

You can also use replace(tzinfo=None) for other datetime.

if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):