关于python:django 1.4 – 无法比较offset-naive和offset-aware datetimes

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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']

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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下我得到了错误:

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

由于线路

1
if timeDue<now and timeDue>dailyTask.last_completed

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

我已经尝试通过添加pytz.utc作为参数使timedue timezone变得敏感,但这仍然会引发相同的错误。

我读过一些关于时区的文档,但对于是否只需要让TimeDue TimeZone知道,或者是否需要对我的数据库和现有数据进行基本的更改,我感到困惑。


查看完整的文档以了解详细信息。

通常,使用django.utils.timezone.now生成一个偏移感知的当前日期时间

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

django.utils.timezone.make_aware进行偏移感知日期时间

1
2
>>> 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>)

然后,您可以比较两个具有偏移感知的日期时间(不带故障)。

此外,您可以通过去掉时区信息,将offset awared datetime转换为offset naive datetime,然后将其与UTC下的正常datetime.datetime.now()进行比较。

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

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