我试图比较当前日期和时间与使用比较运算符在模型中指定的日期和时间:

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

脚本错误如下:

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

模型是这样的:

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()

我也有django使用区域日期和时间。

我还没有找到的是django使用DateTimeField()的格式。是天真还是有意识?我如何得到datetime.now()识别区域日期时间?


当前回答

默认情况下,在Python中datetime对象是naive,因此需要将它们都设置为naive或感知型datetime对象。这可以使用:

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

注意:如果已经设置了tzinfo,这将引发ValueError。如果你不确定,那就用

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

顺便说一下,您可以在datetime中格式化UNIX时间戳。带有时区信息的Datetime对象,如下所示

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)

其他回答

只是:

dt = datetimeObject.strftime(format) # format = your datetime format ex) '%Y %d %m'
dt = datetime.datetime.strptime(dt,format)

所以这样做:

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')

然后使用start_time和end_time

Datetime.datetime.now不是时区感知的。

Django为此提供了一个帮助程序,它需要pytz

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

您应该能够将现在与challenge.datetime_start进行比较

一行代码解决方案

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

总结

您必须将时区信息添加到now() datetime中。 但是,必须添加与引用变量相同的时区;这就是为什么我首先读取tzinfo属性。

您正在尝试为date_time设置时区,而date_time已经有一个时区。 使用replace和astimezone函数。

local_tz = pytz.timezone('Asia/Kolkata')

current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(local_tz)

默认情况下,在Python中datetime对象是naive,因此需要将它们都设置为naive或感知型datetime对象。这可以使用:

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

注意:如果已经设置了tzinfo,这将引发ValueError。如果你不确定,那就用

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

顺便说一下,您可以在datetime中格式化UNIX时间戳。带有时区信息的Datetime对象,如下所示

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)