Django 过滤器 __date 时区感知

ano*_*ous 5 django timezone datetime

认为

  1. 我正在使用 Django 2.x 并使用默认设置。即,TIME_ZONE = 'UTC'USE_TZ = True

  2. 我正在夏威夷檀香山记录数据,这意味着檀香山的 2019-4-9 晚上 9 点(用户时间)是 UTC(服务器时间)的 2019-4-10

现在我想按 2019-4-9 Honolulu 时间(用户时间)过滤

这是一个演示代码

class TimelineTable(models.Model):
    accessed = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'{self.accessed}'
Run Code Online (Sandbox Code Playgroud)

这是TimelineTable中的数据(记录于2019-4-9檀香山时间

ID      accessed       
1       2019-04-10 07:19:30.319881 
2       2019-04-10 07:19:35.004506
3       2019-04-10 07:19:37.612088
Run Code Online (Sandbox Code Playgroud)

不考虑时区,获取数据工作正常

ID      accessed       
1       2019-04-10 07:19:30.319881 
2       2019-04-10 07:19:35.004506
3       2019-04-10 07:19:37.612088
Run Code Online (Sandbox Code Playgroud)

现在的问题是时区。

我在和服务器说话:嘿,给我那些我在 2019-4-9 在檀香山录制的条目。

>>> TimelineTable.objects.filter(accessed__date=datetime.date(2019, 4, 9))
<QuerySet []>
>>> TimelineTable.objects.filter(accessed__date=datetime.date(2019, 4, 10))
<QuerySet [<TimelineTable: 2019-04-10 07:19:30.319881+00:00>, <TimelineTable: 2019-04-10 07:19:35.004506+00:00>, <TimelineTable: 2019-04-10 07:19:37.612088+00:00>]>
Run Code Online (Sandbox Code Playgroud)

我预计有 3 个条目,但没有任何反应。

如何获得这些条目,没有任何错误?

rud*_*dra 2

我认为这应该有效:

t = datetime.datetime(2019, 4, 9, 14, 00, 00, tzinfo=Honolulu)
d = t.astimezone(pytz.UTC)
TimelineTable.objects.filter(accessed__date=d.date())
# OR 
TimelineTable.objects.filter(accessed__gte=t)
Run Code Online (Sandbox Code Playgroud)

以下代码将不起作用

t = datetime.datetime(2019, 4, 9, tzinfo=Honolulu)
d = t.astimezone(pytz.UTC)
TimelineTable.objects.filter(accessed__date=d.date())
Run Code Online (Sandbox Code Playgroud)

解释

当你生成时datetime.datetime(2019, 4, 9),它会返回时间datetime.time(0, 0)。当您将其转换为 时UTC,日期不会改变,因为它不是 UTC 和檀香山之间的时差不是 24 小时。