2

在我的应用程序中,我使用时USE_TZ=Truedatetimedjango.util.timezone.now

@classmethod
def asUTCDate(cls, date):
        if not timezone.is_aware(date):
            return timezone.make_aware(date, timezone.utc)
        return date.replace(tzinfo=timezone.utc)

我还使用此代码段(如文档中建议的那样)强制检查幼稚/感知日期:

import warnings
warnings.filterwarnings(
        'error', r"DateTimeField .* received a naive datetime",
        RuntimeWarning, r'django\.db\.models\.fields')

到目前为止,据我所知,这是正确的方法(这是 django 文档中的引述:解决此问题的方法是在代码中使用 UTC,并且仅在与最终用户交互时使用本地时间。),似乎我的应用程序处理日期非常好......但我刚刚针对使用 Django 1.6 的模型实现了一个过滤器__hour,它强制基于用户时区进行提取,结果类似于:

django_datetime_extract('hour', "object"."date", Europe/Rome) = 15

但这打破了我的查询,因为我期望的一些结果不包含在集合中,但是当我使用 a__range在日期之间搜索时,它似乎按预期工作(返回日期在范围内的对象)......所以它似乎我认为 Django 仅在过滤器的查询中考虑时区__hour......但我不明白为什么......我假设除了在显示日期根据用户 tz 格式化的模板中之外,UTC 无处不在,但也许这不是真的。所以我的问题是:我使用时区的方式对吗?是__hour过滤器错误还是什么?

4

1 回答 1

4

似乎您对日期的处理是正确的。但是,任何与日期相关的功能(例如按小时过滤)的所有文档都包含以下注释:

当 USE_TZ 为 True 时,日期时间字段在过滤前转换为当前时区。

对于range过滤器,此注释不存在,因为它不仅range可以用于过滤日期,还可以用于过滤其他类型,例如整数和字符。即它不一定知道日期时间。

从本质上讲,问题归结为:您在本地时区的“与用户交互”与 UTC 时间的内部时间之间的界限在哪里?在您的情况下,您可以想象用户在搜索框中输入以搜索小时==3。这是否意味着例如您的表单代码应该在 hour==3 和 UTC 等效值之间进行转换?这将需要一个特殊的forms.HourField。或者也许应该将值 (3) 直接提供给我们知道我们正在搜索小时字段的查询,因此需要进行转换。

我们真的必须遵循这个文档。

  • 将使用任何专门的日期/时间过滤功能针对日期/时间字段进行过滤的值将被视为位于用户的本地时区。
  • 如果range对日期使用过滤器,则不会发生时间转换,因此您需要将用户输入的本地时间值转换为 UTC。
于 2013-11-11T23:14:12.960 回答