问题
Assume
I am using Django 2.x and use default settings. i.e,
TIME_ZONE = 'UTC'andUSE_TZ = TrueI am recording data in Honolulu, Hawaii, which means 2019-4-9 9pm (user time) in Honolulu is 2019-4-10 in UTC (server time)
Now I want to filter by 2019-4-9 Honolulu time (user time)
Here is what a demo code
class TimelineTable(models.Model):
accessed = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.accessed}'
Here is the data in TimelineTable (recorded in 2019-4-9 Honolulu time)
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
Without considering timezone, fetch data works fine
>>> 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>]>
Now the problem is with timezone.
I am talking to server: Hey, give me those entries I recorded in 2019-4-9 at Honolulu.
>>> Honolulu = pytz.timezone("Pacific/Honolulu")
>>> t = datetime.datetime(2019, 4, 9, tzinfo=Honolulu)
>>> TimelineTable.objects.filter(accessed__date=t)
<QuerySet []>
I expected 3 entries, but nothing happens.
How to get these entries, without any bugs?
回答1:
I think this should work:
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)
Following code will not work:
t = datetime.datetime(2019, 4, 9, tzinfo=Honolulu)
d = t.astimezone(pytz.UTC)
TimelineTable.objects.filter(accessed__date=d.date())
Explanation
When you generate datetime.datetime(2019, 4, 9), it will return time datetime.time(0, 0). When you convert it to UTC, the date won't be changed because its not the time difference between UTC and Honolulu is not 24 hours.
来源:https://stackoverflow.com/questions/55607796/django-filter-date-with-timezone-aware