Django 1.6过滤小时和时区问题

时间:2013-11-11 22:33:20

标签: django date datetime timezone

在我的应用程序中,我使用时区(USE_TZ=True),我在代码中创建的所有日期都知道UTC datetime个对象(我使用django.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的模型实现了过滤器{{1}并且它根据用户时区强制提取,结果类似于:

__hour

但这打破了我的查询,因为我期待的一些结果不包含在集合中,但当我使用django_datetime_extract('hour', "object"."date", Europe/Rome) = 15 在日期之间搜索时,它似乎按预期工作(具有日期范围的对象)返回)...所以在我看来,Django只在__range过滤器的查询中考虑时区...但我不明白为什么......我假设UTC除了在显示日期的模板中以外的任何地方都使用根据用户tz格式化,但也许这不是真的。 所以我的问题是:我正在使用时区的方式吗? __hour过滤器错误或是什么?

1 个答案:

答案 0 :(得分:4)

好像你正在用日期做正确的事情。但是,任何与日期相关的功能的所有文档(例如按小时过滤)都包含以下注释:

  

当USE_TZ为True时,datetime字段将转换为当前时间   过滤前的区域。

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

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

我们必须遵循这个文档。

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