django 1.4-无法比较原始偏移和知道偏移的日期时间


85

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

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

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']

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

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下我会收到错误消息:

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

由于线

if timeDue<now and timeDue>dailyTask.last_completed

并且两个比较子句都会引发此错误。

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

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

Answers:


168

检查详尽的文档以获取详细信息。

通常,用于django.utils.timezone.now设置可感知偏移的当前日期时间

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

django.utils.timezone.make_aware设置一个可偏移的日期时间

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

然后,您可以比较没有偏移的两个可感知偏移的日期时间。

此外,您可以通过剥离时区信息将偏移唤醒的日期时间转换为原始偏移的日期时间,然后可以datetime.datetime.now()在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.py生成的文件),那么,如果您的数据库支持时区感知时间,则与时间相关的模型字段的值将为时区感知。您可以通过在设置中设置(或直接删除)来禁用它。django-admin.py startprojectTrueUSE_TZ=FalseUSE_TZ=True


4
Django不存储TimeField的感知时间,仅存储DateTimeField。确实很烦人,因为python datetime.time对象确实支持TZINFO,就像datetime.datetime对象一样。我不知道他们会在下一个版本中对其进行修复。顺便说一句,我已经在postres 9.1数据库服务器上对其进行了测试。
tejinderss

@tejinderss:datetime.time是错误的。'Asia/Shanghai'如果您不知道日期,则没有时间存储时区(utc偏移量可能在同一时间但在不同日期可能有所不同)。
jfs

@okm:make_aware(datetime.now(), get_default_timezone())如果get_default_timezone()与您当地的时区不同,则失败(应该是,但是不是完全可信赖的)。只需使用timezone.now()代替(如果USE_TZ是,则可以识别时区True)。
jfs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.