django 1.4 - 无法比较 offset-naive 和 offset-aware 日期时间

2022-01-16 00:00:00 python django timezone

问题描述

我正在将应用程序从 django 1.2 迁移到 1.4.

I am in the process of migrating an application from django 1.2 To 1.4.

我有一个每日任务对象,其中包含该任务应该完成的时间:

I have a daily task object which contains a time of day that task should be completed:

class DailyTask(models.Model):
    time = models.TimeField()
    last_completed = models.DateTimeField()
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    weekends = models.BooleanField()

    def __unicode__(self):
        return '%s' % (self.name)

    class Meta:
        db_table = u'dailytask'
        ordering = ['name']

为了检查今天是否还需要完成任务,我有以下代码:

In order to check if a task is still required to be completed today, I have the following code:

def getDueDailyTasks():
    dueDailyTasks=[]
    now = datetime.datetime.now()
    try:
        dailyTasks = DailyTask.objects.all()
    except dailyTask.DoesNotExist:
        return None
    for dailyTask in dailyTasks:
        timeDue = datetime.datetime(now.year,now.month,now.day,dailyTask.time.hour,dailyTask.time.minute,dailyTask.time.second)
        if timeDue<now and timeDue>dailyTask.last_completed:
            if dailyTask.weekends==False and now.weekday()>4:
                pass
            else:
                dueDailyTasks.append({'id':dailyTask.id,
                            'due':timeDue,
                             'name': dailyTask.name,
                             'description':dailyTask.description})
    return dueDailyTasks

这在 1.2 下运行良好,但在 1.4 下我得到了错误:

This worked fine under 1.2, But under 1.4 I get the error:

can't compare offset-naive and offset-aware datetimes

由于线路

if timeDue<now and timeDue>dailyTask.last_completed

两个比较子句都会抛出这个错误.

and both comparison clauses throw this error.

我尝试通过添加 pytz.UTC 作为参数来识别 timeDue 时区,但这仍然会引发相同的错误.

I have tried making timeDue timezone aware by adding pytz.UTC as an argument, but this still raises the same error.

我已经阅读了一些关于时区的文档,但是对于我是否只需要让 timeDue 时区感知,或者我是否需要对我的数据库和现有数据进行根本性更改感到困惑.

I've read some of the docs on timezones but am confused as to whether I just need to make timeDue timezone aware, or whether I need to make a fundamental change to my db and existing data.


解决方案

检查 详尽的文档了解详细信息.

通常,使用 django.utils.timezone.now 来制作可感知偏移的当前日期时间

Normally, use django.utils.timezone.now to make an offset-aware current datetime

>>> from django.utils import timezone
>>> timezone.now()
datetime.datetime(2012, 5, 18, 13, 0, 49, 803031, tzinfo=<UTC>)

django.utils.timezone.make_aware 制作偏移感知日期时间

And django.utils.timezone.make_aware to make an offset-aware datetime

>>> timezone.make_aware(datetime.datetime.now(), timezone.get_default_timezone())
datetime.datetime(2012, 5, 18, 21, 5, 53, 266396, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

然后,您可以比较两个可感知偏移的日期时间而不会遇到麻烦.

You could then compare both offset-aware datetimes w/o trouble.

此外,您可以通过剥离时区信息将偏移感知日期时间转换为偏移天真日期时间,然后可以在 utc 下与普通 datetime.datetime.now() 进行比较.

Furthermore, you could convert offset-awared datetime to offset-naive datetime by stripping off timezone info, then it could be compared w/ normal datetime.datetime.now(), under utc.

>>> t = timezone.now() # offset-awared datetime
>>> t.astimezone(timezone.utc).replace(tzinfo=None)
datetime.datetime(2012, 5, 18, 13, 11, 30, 705324)

USE_TZTrue '默认情况下' (实际上它是 False 默认情况下,但是 settings.pydjango-admin.py startproject 生成的文件将其设置为 True),那么如果您的数据库支持时区感知时间,则与时间相关的模型字段的值将是 timezone-知道的.您可以通过在设置中设置 USE_TZ=False(或简单地删除 USE_TZ=True)来禁用它.

USE_TZ is True 'by default' (actually it's False by default, but the settings.py file generated by django-admin.py startproject set it to True), then if your DB supports timezone-aware times, values of time-related model fields would be timezone-aware. you could disable it by setting USE_TZ=False(or simply remove USE_TZ=True) in settings.

相关文章