Запрос часового пояса на MongoDB - PullRequest
1 голос
/ 12 февраля 2020

Я создаю приложение, в котором пользователи могут находиться в разных часовых поясах, а выполняемые мной запросы чувствительны к их часовым поясам.

Проблема, с которой я столкнулся, заключается в том, что MongoDB, похоже, игнорирует часовой пояс по запросу!

Это пример поля даты "2019-09-29T23: 52: 13.495000 + 13: 00", вот полное json: enter image description here

И это пример запроса:

{
   "at": {
      "$gte": "2019-09-29T00:00:00+00:00",
      "$lte": "2019-09-30T00:00:00+00:00"
   }
}

Все мои даты сохраняются с +12 или +13, потому что это часовые пояса, в которых мои клиенты находятся в данный момент, По сути, это означает, что для вышеприведенного запроса я должен увидеть некоторые результаты с 2019-10-01: 00: 00: 00 + 13: 00, поскольку первое октября по-прежнему 30 сентября в UT C. , и я не.

Я новичок в этом и не слишком далеко вниз по кроличьей норе, так что я открыт для рефакторинга / изменения мышления, если это облегчит ситуацию.

Для контекста, если это имеет значение, я использую PyMon go, и моя версия MongoDB 4.2

РЕДАКТИРОВАТЬ! Я пытался преобразовать поле "at" в дату, но часовой пояс, кажется, был подавлен или не виден enter image description here

С этим мне также пришлось изменить способ, которым я запрос

{ "at": { 
    "$gte": ISODate("2019-09-29T00:00:00+00:00"), 
    "$lte": ISODate("2019-09-30T00:00:00+00:00") 
   } 
}

не помог

1 Ответ

1 голос
/ 13 февраля 2020

MongoDB использует часовой пояс UT C, когда сохраняет дату. Используя ваш пример даты:

> ISODate("2019-09-29T23:52:13.495000+13:00")
ISODate("2019-09-29T10:52:13.495Z")

Таким образом, часовой пояс +13:00 преобразуется в Z (UT C), используя ISODate(), и это значение сохраняется в базе данных.

> db.test.insert({_id:0, at: ISODate("2019-09-29T23:52:13.495000+13:00")})

> db.test.find()
{ "_id" : 0, "at" : ISODate("2019-09-29T10:52:13.495Z") }

Обратите внимание, что "at" сохраняется во времени UT C вместо +13 в том виде, в котором оно было вставлено.

Запрос с использованием ISODate() в соответствии с вашим примером работает должным образом:

> db.test.find({ "at": {
...     "$gte": ISODate("2019-09-29T00:00:00+00:00"),
...     "$lte": ISODate("2019-09-30T00:00:00+00:00")
...    }
... })
{ "_id" : 0, "at" : ISODate("2019-09-29T10:52:13.495Z") }

Информация о часовом поясе не отображается из-за используемого вами визуального инструмента. Он отображается в оболочке mongo как Z, как в приведенном выше примере.

Преимущество хранения UT C заключается в том, что вы можете преобразовывать их в любые другие часовые пояса, не беспокоясь о переходе на летнее время. , Существуют операторы агрегации с указанием даты c, которые работают с часовыми поясами и выполняют конвертацию между ними. См. Операторы выражения даты и { ссылка } для примеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...