【问题标题】:Django 1.6 filter by hour and time zone issueDjango 1.6 按小时和时区问题过滤
【发布时间】:2013-11-23 21:36:57
【问题描述】:

在我的应用程序中,我使用时区 (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)

我还使用这个 sn-p 强制检查幼稚/感知日期(如文档中建议的那样):

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

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

【问题讨论】:

    标签: django date datetime timezone


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 很好的解释。 WRT 最后两点,请注意“用户的本地时区”== Django 的当前时区,前提是您已经实现了当前时区中间件(在文档中描述),并且您“期望转换用户输入的本地时区”仅当您的默认时间值是 UTC(应该是!)时,才将时间值“转换为 UTC”
    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 2013-11-26
    • 2014-03-22
    • 2014-03-12
    • 2023-03-23
    • 2011-06-15
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多