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

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()识别区域日期时间?


当前回答

如果您正在使用SQLAlchemy并存储DateTime,那么您可以将它与时区信息一起存储。这将允许您将该DateTime与时区感知的DateTimes进行比较。示例:SQLAlchemy核心中的列定义:

Column("created_at", DateTime(timezone=True), nullable=False)

其他回答

在我的例子中,我已经用pytz控制了时区,我已经用django.utils的时区将日期转换为本机:

import pytz
from django.utils import timezone

def _my_method(native_date, timezone):
    aware_date = datetime.now(pytz.timezone(timezone))
    return timezone.make_naive(aware_date) >  native_date

你也可以使用timezone.make_aware来感知本地日期

一行代码解决方案

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属性。

所以我解决这个问题的方法是确保两个日期时间在正确的时区。

我可以看到你正在使用datetime.now(),它将返回系统当前时间,没有tzinfo设置。

Tzinfo是附加到datetime上的信息,用于让它知道自己所在的时区。如果使用naive datetime,则需要在整个系统中保持一致。我强烈建议只使用datetime.utcnow()

当你在某个地方创建有tzinfo关联的datetime时,你需要做的是确保这些被本地化(有tzinfo关联)到正确的时区。

看看德罗宁,它让处理这种事情变得容易多了。

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

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

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

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

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

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

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