#django #datetime #timezone
#django #дата и время #Часовой пояс
Вопрос:
Предположим
-
Я использую Django 2.x и использую настройки по умолчанию. то есть,
TIME_ZONE = 'UTC'
иUSE_TZ = True
-
Я записываю данные в Гонолулу, Гавайи, что означает, что 2019-4-9 9 вечера (время пользователя) в Гонолулу — 2019-4-10 по UTC (серверное время)
Теперь я хочу отфильтровать по времени Гонолулу 2019-4-9 (время пользователя)
Вот что такое демонстрационный код
class TimelineTable(models.Model):
accessed = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.accessed}'
Вот данные в 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
Без учета часового пояса выборка данных работает нормально
>>> 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>]>
Теперь проблема с часовым поясом.
Я разговариваю с сервером: Эй, дай мне те записи, которые я записал в 2019-4-9 годах в Гонолулу.
>>> Honolulu = pytz.timezone("Pacific/Honolulu")
>>> t = datetime.datetime(2019, 4, 9, tzinfo=Honolulu)
>>> TimelineTable.objects.filter(accessed__date=t)
<QuerySet []>
Я ожидал 3 записи, но ничего не происходит.
Как получить эти записи без каких-либо ошибок?
Комментарии:
1. Каково значение
USE_TZ
переменной settings?2. как упоминалось выше, все настройки по умолчанию. т.е. USE_TZ = True
Ответ №1:
Я думаю, это должно сработать:
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)
Следующий код не будет работать:
t = datetime.datetime(2019, 4, 9, tzinfo=Honolulu)
d = t.astimezone(pytz.UTC)
TimelineTable.objects.filter(accessed__date=d.date())
Объяснение
При генерации datetime.datetime(2019, 4, 9)
он вернет время datetime.time(0, 0)
. Когда вы преобразуете его в UTC
, дата не будет изменена, потому что разница во времени между UTC и Гонолулу не составляет 24 часов.
Комментарии:
1. Я вижу. 2019-4-9 в Гонолулу, утром и вечером, фактически включает два дня по UTC. Я думаю, мне не следует использовать date