无法比较naive和aware的datetime.now() <= challenge.datetime_end
我正在尝试用比较运算符来比较当前的日期和时间与模型中指定的日期和时间:
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()识别本地的日期和时间呢?
16 个回答
136
一行代码解决方案
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()
时间加上时区信息。
不过,你必须加上和参考变量相同的时区,这就是我为什么先读取 tzinfo
属性的原因。
172
datetime.datetime.now
这个函数获取的时间是没有时区信息的。
Django 提供了一个工具来处理这个问题,但需要用到 pytz
这个库。
from django.utils import timezone
now = timezone.now()
你应该可以把 now
和 challenge.datetime_start
进行比较。
314
在Python中,默认情况下,datetime
对象是naive
的,也就是说它不包含时区信息。因此,你需要确保两个datetime
对象要么都是naive
的,要么都是带有时区信息的aware
对象。你可以通过以下方式来做到这一点:
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)
顺便提一下,你可以用以下方法将UNIX时间戳格式化为带有时区信息的datetime.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)