这似乎应该很容易,但它实际上是一个不平凡的问题,主要由于时区。您的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:日期和时间的正确处理是很难的。希望这可以帮助;祝你好运!