在我的应用程序中,我使用时区(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
过滤器错误或是什么?
答案 0 :(得分:4)
好像你正在用日期做正确的事情。但是,任何与日期相关的功能的所有文档(例如按小时过滤)都包含以下注释:
当USE_TZ为True时,datetime字段将转换为当前时间 过滤前的区域。
对于range
过滤器,此注释不存在,因为range
不仅可用于过滤日期,还可用于其他类型(如整数和字符)。即它不一定是日期时间。
从本质上讲,问题归结为:在哪里划分“与用户交互”(时间在本地时区)和内部时间以UTC为单位的界限?在您的情况下,您可以想象用户在搜索框中输入以搜索小时== 3。这是否意味着您的表单代码应该在hour == 3和UTC等效之间进行转换?这将需要一个特殊的form.HourField。或者值(3)应该直接提供给我们知道我们在小时字段上搜索的查询,因此需要进行转换。
我们必须遵循这个文档。
range
过滤器,则不会发生时间转换,因此您需要将用户输入的本地时间值转换为UTC。