I am trying to compare the current date and time with dates and times specified in models using comparison operators:
if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:
The script errors out with:
TypeError: can't compare offset-naive and offset-aware datetimes
The models look like this:
class Fundraising_Challenge(models.Model): name = models.CharField(max_length=100) datetime_start = models.DateTimeField() datetime_end = models.DateTimeField()
I also have django using locale date and times.
What I haven't been able to find is the format django uses for DateTimeField(). Is it naive or aware? And how do I get datetime.now() to recognize locale datetime?
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
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)
datetime.datetime.now is not timezone aware.
Django comes with a helper for this, which requires
from django.utils import timezone now = timezone.now()
You should be able to compare
if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo): pass #some code
# 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
You must add the timezone info to your
However, you must add the same timezone of the reference variable; that is why I first read the
Disable time zone.
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):
So the way I would solve this problem is to make sure the two datetimes are in the right timezone.
I can see that you are using
datetime.now() which will return the systems current time, with no tzinfo set.
tzinfo is the information attached to a datetime to let it know what timezone it is in. If you are using naive datetime you need to be consistent through out your system. I would highly recommend only using
seeing as somewhere your are creating datetime that have tzinfo associated with them, what you need to do is make sure those are localized (has tzinfo associated) to the correct timezone.
Take a look at Delorean, it makes dealing with this sort of thing much easier.
It is working form me. Here I am geeting the table created datetime and adding 10 minutes on the datetime. later depending on the current time, Expiry Operations are done.
from datetime import datetime, time, timedelta import pytz
Added 10 minutes on database datetime
table_datetime = '2019-06-13 07:49:02.832969' (example)
# Added 10 minutes on database datetime # table_datetime = '2019-06-13 07:49:02.832969' (example) table_expire_datetime = table_datetime + timedelta(minutes=10 ) # Current datetime current_datetime = datetime.now() # replace the timezone in both time expired_on = table_expire_datetime.replace(tzinfo=utc) checked_on = current_datetime.replace(tzinfo=utc) if expired_on < checked_on: print("Time Crossed) else: print("Time not crossed ")
It worked for me.
You are trying to set the timezone for date_time which already has a timezone.
local_tz = pytz.timezone('Asia/Kolkata') current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(local_tz)
dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m' dt = datetime.datetime.strptime(dt,format)
So do this:
start_time = challenge.datetime_start.strftime('%Y %d %m %H %M %S') start_time = datetime.datetime.strptime(start_time,'%Y %d %m %H %M %S') end_time = challenge.datetime_end.strftime('%Y %d %m %H %M %S') end_time = datetime.datetime.strptime(end_time,'%Y %d %m %H %M %S')
and then use