Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 预保存信号中的datetime.time()比较问题_Django_Python 3.x_Datetime_Django Models_Django Timezone - Fatal编程技术网

Django 预保存信号中的datetime.time()比较问题

Django 预保存信号中的datetime.time()比较问题,django,python-3.x,datetime,django-models,django-timezone,Django,Python 3.x,Datetime,Django Models,Django Timezone,我有这些模型: class Interval(models.Model): from_time = models.TimeField(auto_now_add=False) to_time = models.TimeField(auto_now_add=False) class CheckIn(models.Model): date_time = models.DateTimeField(auto_now_add=True) interval = models.

我有这些模型:

class Interval(models.Model):
    from_time = models.TimeField(auto_now_add=False)
    to_time = models.TimeField(auto_now_add=False)

class CheckIn(models.Model):
    date_time = models.DateTimeField(auto_now_add=True)
    interval = models.ForeignKey(Interval, on_delete=models.SET_NULL)
主要目标是:

创建
签入时
代码应检查它是否在给定的时间间隔内。我需要比较这两者并以
%H:%M:%S
格式返回它们的差异

到目前为止我所做的:

由于我有不同的场景,在保存前如何处理给定的
签入
,因此我使用
pre_save
信号,时间比较是这些场景的一部分。下面是一个伪:

@receiver(pre_save, sender=CheckIn)
def set_action_state(sender, instance, **kwargs):
    if something:
       ...
       if another:
          ...
       else:
          ...
    else:
        # instance.date_time.time() is 13:56:56.568860 (2 hours behind, it should be 15 instead of 13)
        # instance.interval.from_time is 15:07:40
        if instance.date_time.time() < instance.interval.from_time:
            # this returns True when it's meant to return False
我尝试的第二件事是将instance.interval.from_time转换为aware datetime,然后比较两个日期的时间()

现在
dt1
dt2
都意识到了这一点,但仍然无法比较它们。以下是完整的代码:

tz = pytz.timezone('Europe/Sofia')
dt1 = instance.date_time.replace(tzinfo=tz)
dt2 = time_to_datetime(dt1.date(), instance.interval.from_time)
print(dt1.time() < dt2.time()) # this is True
print(dt1.tzinfo) # 'Europe/Sofia'
print(dt2.tzinfo) # 'Europe/Sofia'
print(dt1.time()) # 13:56:56.568860
print(dt1.time()) # 15:07:40
tz=pytz.时区(“欧洲/索非亚”)
dt1=instance.date\u time.replace(tzinfo=tz)
dt2=时间到日期时间(dt1.date(),instance.interval.from\u time)
打印(dt1.time()
如何在
dt1
中获得正确的时间,并使此比较正常工作,即使两个日期时间都使用正确的时区?


编辑:我在我的设置中使用了
USE_TZ=True

我在谷歌上搜索了一下,发现django打算总是以
UTC
格式保存在模型中,但在从db中检索时,会转换为设置设置设置的时区。因此,我认为在pre-save实例中有可能使用
UTC
格式。我可能是错的,因为我对它没有具体的、强有力的了解

我认为这种比较需要实时进行。因此,现在使用用户时区与从用户时区开始的时间间隔进行比较是非常安全的。所以我的建议

import pytz
import datetime


tz = pytz.timezone('Europe/Sofia')
curtime = tz.localize(datetime.datetime.now())
并转换这行代码

  if instance.date_time.time() < instance.interval.from_time:
            # this returns True when it's meant to return False
如果instance.date\u time.time()

如果curtime
Django不保证Python代码中日期时间的时区。这是因为1)时区主要与用户交互相关(这就是为什么
activate()
会影响表单和模板),2)Python比较操作具有时区意识,因此特定的时区不会影响结果

当然,一个不知道时区的操作是从datetime提取时间并将其与另一个时间进行比较。因此,您必须手动将日期时间转换为正确的时区。您的想法是正确的,但是
replace()
是错误的方法。(它不只是转换到另一个时区,而是在时间上改变实际时刻。)

相反,请执行以下操作:

from django.utils.timezone import localtime

if localtime(instance.date_time).time() < instance.interval.from_time:
    pass
从django.utils.timezone导入localtime
如果localtime(instance.date\u time).time()
您能否再次尝试创建新的间隔并签入,然后在更改
实例.date\u time.replace(tzinfo=tz)
后在pre\u save中进行比较?不幸的是,结果相同。您是否在设置中添加USE\u tz=True?是的,我将更新我的问题。不幸的是,这会抛出
值错误:不是原始日期时间(tzinfo已设置)
对此我真的很抱歉。由于您已经设置了时区,请尝试使用timeZone.now()我的datetime.datetime对象已经可以识别时区,因此无需将其替换为timeZone.now(),它将产生相同的错误。这正是我所需要的。我知道用户的
datetime
和python的
datetime
之间存在差异,但我认为将它们转换为相等的时区也会在python中转换它们的日期和时间。明亮的
  if instance.date_time.time() < instance.interval.from_time:
            # this returns True when it's meant to return False
   if curtime < instance.interval.from_time:
            # I hope this return False now
from django.utils.timezone import localtime

if localtime(instance.date_time).time() < instance.interval.from_time:
    pass