Фильтр Django __дата с учетом часового пояса

#django #datetime #timezone

#django #дата и время #Часовой пояс

Вопрос:

Предположим

  1. Я использую Django 2.x и использую настройки по умолчанию. то есть, TIME_ZONE = 'UTC' и USE_TZ = True

  2. Я записываю данные в Гонолулу, Гавайи, что означает, что 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