这看起来应该很容易,但实际上这是一个重要的问题,主要是由于时区。您的DateTimeField 存储特定时间点。该时间点发生在哪个日期在不同时区可能不同 - 完全相同的时间点可能是柏林的星期三早上,但旧金山的星期二晚上。
给定您要查询的日期和时区,策略如下:
1) 为“该时区的那一天的开始”构造一个日期时间,为“该时区的那一天的结束”构造一个日期时间。
2) 查询在您的开始和结束日期时间之间带有date_created 的页面。
在我最近编写的一些代码中,我有一个 combine 函数用于将日期、时间和时区组合成日期时间:
from django.utils import timezone
import pytz
def combine(adate, atime, tz=None, is_dst=None):
"""Turn a date and a time into a datetime in given timezone (or default).
The ``is_dst`` argument controls the handling of ambiguous datetimes
(e.g. during fall DST changeover), and nonexistent datetimes (e.g. during
spring DST changeover). If it is ``None`` (the default), these cases will
return ``None`` instead of a datetime. If it is ``True``, these cases will
be resolved by always assuming DST, and if ``False`` by assuming no-DST.
"""
tz = tz or timezone.get_current_timezone()
naive = dt(adate.year, adate.month, adate.day, atime.hour, atime.minute)
try:
return tz.normalize(tz.localize(naive, is_dst=is_dst))
except pytz.InvalidTimeError:
return None
那么您的查询如下所示:
def get_pages_created_on_date(for_date):
start = combine(for_date, time(0))
end = combine(for_date + datetime.timedelta(days=1), time(0))
return Page.objects.filter(date_created__gte=start, date_created__lt=end)
该版本仅使用当前激活的时区(这可能是您的 Django 设置文件中配置的时区,除非您已完成一些额外的工作来为当前请求的用户激活本地时区)。
我不知道 DST 转换发生在午夜的任何时区,这应该可以使此代码安全地避免 DST 转换问题。但如果存在这样的时区,并且您可能需要在其中处理日期时间,那么您的查询函数需要将 is_dst 标志传递给 combine。
如果您将today 传递给此查询,您还必须考虑如何为today 生成日期值。致电datetime.date.today() 将始终为您提供服务器操作系统本地时区的今天日期。这可能与您的 Django 设置时区或当前激活的 Django 时区不对应,这将导致查询无法给出正确的结果。为了正确处理时区,您应该使用这样的today 函数:
from django.utils import timezone
def today():
return timezone.localtime(timezone.now()).date()
TL;DR:正确处理日期和时间很困难。希望这可以帮助;祝你好运!