无法比较天真和意识到datetime.now()<= challenge.datetime_end

Sco*_*ott 119 python django comparison datetime

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

if challenge.datetime_start <= datetime.now() <= challenge.datetime_end:
Run Code Online (Sandbox Code Playgroud)

脚本错误出现:

TypeError: can't compare offset-naive and offset-aware datetimes
Run Code Online (Sandbox Code Playgroud)

模型看起来像这样:

class Fundraising_Challenge(models.Model):
    name = models.CharField(max_length=100)
    datetime_start = models.DateTimeField()
    datetime_end = models.DateTimeField()
Run Code Online (Sandbox Code Playgroud)

我也有使用语言环境日期和时间的django.

我无法找到的是django用于DateTimeField()的格式.是天真还是意识到?如何让datetime.now()识别区域设置日期时间?

Vir*_*put 94

默认情况下,datetime对象是naivePython,因此您需要将它们都设置为天真或有意识的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
Run Code Online (Sandbox Code Playgroud)

注意:这会引发ValueErrorif tzinfo已设置.如果您不确定,请使用

start_time = challenge.datetime_start.replace(tzinfo=utc)
end_time = challenge.datetime_end.replace(tzinfo=utc)
Run Code Online (Sandbox Code Playgroud)

顺便说一下,您可以使用时区信息格式化datetime.datetime对象中的UNIX时间戳,如下所示

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)
Run Code Online (Sandbox Code Playgroud)

  • 替换 `tzinfo` 不会做任何转换,使得比较不正确。 (4认同)
  • 您可以从“datetime”的“timezone”模块获取“utc”时区。`时区.utc`。 (3认同)
  • 它说: ValueError: Not naive datetime (tzinfo is not set) 当它尝试计算时: datetimeStart = utc.localize(challenge.datetime_start) (2认同)

小智 78

datetime.datetime.now 不是时区意识.

Django为此提供了一个帮手,这需要 pytz

from django.utils import timezone
now = timezone.now()
Run Code Online (Sandbox Code Playgroud)

你应该能够比较nowchallenge.datetime_start

  • 如果`USE_TZ = True`则`timezone.now()`返回一个时区感知的datetime对象,即使没有安装`pytz`(尽管可能因其他原因建议安装). (2认同)

ePi*_*314 39

一行代码解决方案

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code
Run Code Online (Sandbox Code Playgroud)

解释版本:

# 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
Run Code Online (Sandbox Code Playgroud)

摘要:
您必须将时区信息添加到now()日期时间.
但是,您必须添加引用变量的相同时区; 这就是我第一次阅读该tzinfo属性的原因.

  • 这似乎是最合乎逻辑的方法 - 谢谢! (3认同)

ovo*_*ovo 15

没有第三方,只有本机日期时间模块。

from datetime import datetime, timedelta, timezone

time1 = datetime.strptime('2021-07-15T00:22:02+0000', '%Y-%m-%dT%H:%M:%S%z')
time2 = datetime(2021, 7, 15, tzinfo=timezone(offset=timedelta()))
if time1 < time2:
    print(True)
Run Code Online (Sandbox Code Playgroud)

  • @jtlz2,你会使用“datetime.now().replace(tzinfo=timezone(offset=timedelta()))” (3认同)

小智 9

禁用时区.使用challenge.datetime_start.replace(tzinfo=None);

您还可以使用replace(tzinfo=None)其他日期时间.

if challenge.datetime_start.replace(tzinfo=None) <= datetime.now().replace(tzinfo=None) <= challenge.datetime_end.replace(tzinfo=None):
Run Code Online (Sandbox Code Playgroud)


小智 8

为了让你的 datetime 对象时区不再天真,只需添加以下函数:

datetimeObject.astimezone()
Run Code Online (Sandbox Code Playgroud)