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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15307623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:45:23  来源:igfitidea点击:

Can't compare naive and aware datetime.now() <= challenge.datetime_end

pythondjangodatetimecomparison

提问by sccrthlt

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.

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

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?

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

采纳答案by Viren Rajput

By default, the datetimeobject is naivein Python, so you need to make both of them either naive or aware datetimeobjects. This can be done using:

默认情况下,datetime对象naive在 Python 中,因此您需要使它们都成为原始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

Note: This would raise a ValueErrorif tzinfois already set. If you are not sure about that, just use

注意:这会引发一个ValueErroriftzinfo已经设置。如果您不确定,请使用

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

顺便说一句,您可以使用时区信息在 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)

回答by Alfredo Aguirre

datetime.datetime.nowis not timezone aware.

datetime.datetime.now不知道时区。

Django comes with a helper for this, which requires pytz

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

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

You should be able to compare nowto challenge.datetime_start

你应该能够比较nowchallenge.datetime_start

回答by myusuf3

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.

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

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 datetime.utcnow()

tzinfo 是附加到日期时间的信息,以使其知道它所在的时区。如果您使用天真的日期时间,您需要在整个系统中保持一致。我强烈建议只使用datetime.utcnow()

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.

看到您正在创建的日期时间与 tzinfo 相关联,您需要做的是确保将它们本地化(与 tzinfo 相关联)到正确的时区。

Take a look at Delorean, it makes dealing with this sort of thing much easier.

看看Delorean,它使处理此类事情变得更加容易。

回答by ePi272314

One line of code solution

一行代码解决

if timezone_aware_var <= datetime.datetime.now(timezone_aware_var.tzinfo):
    pass #some code

Explained version

解释版

# 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

Summary

概括

You must add the timezone info to your now()datetime.
However, you must add the sametimezone of the reference variable; that is why I first read the tzinfoattribute.

您必须将时区信息添加到您的now()日期时间。
但是,您必须添加引用变量相同的时区;这就是我首先阅读tzinfo属性的原因。

回答by Amin Fathi

Disable time zone. Use challenge.datetime_start.replace(tzinfo=None);

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

You can also use replace(tzinfo=None)for other datetime.

您也可以replace(tzinfo=None)用于其他日期时间

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

回答by Chandan Sharma

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.

这是我的工作。在这里,我正在创建表创建的日期时间并在日期时间上添加 10 分钟。稍后根据当前时间,到期操作完成。

from datetime import datetime, time, timedelta
import pytz

Added 10 minutes on database datetime

在数据库日期时间上添加了 10 分钟

table_datetime = '2019-06-13 07:49:02.832969' (example)

table_datetime = '2019-06-13 07:49:02.832969'(示例)

# 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.

它对我有用。