У меня проблема с хранением дат в mongodb с разными часовыми поясами с использованием pymongo

#python #mongodb #date #datetime #pymongo

#python #mongodb #Дата #дата и время #pymongo

Вопрос:

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

Как мы все знаем, когда мы сохраняем дату в mongodb, она автоматически преобразует дату нашего часового пояса в UTC, изменяя время, но сохраняя то же абсолютное значение ниже.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я запрашиваю базу данных для получения даты с помощью pymongo, я получаю точно такую же дату и время, которые хранятся в mongodb в UTC, но в моем часовом поясе без изменения преобразования;

например, предположим, что я создаю datetime в python, используя библиотеку «datetime»:

 MY_TIMEZONE = pytz.timezone('America/Bogota')

datetime.now().astimezone(MY_TIMEZONE)
 

и я получаю эту дату в своем часовом поясе:

'2021-02-25 00:00:00-05:00'

посмотрите на -05:00 в конце

когда я сохраняю эту дату в своей коллекции mongodb в atlas, она преобразует дату в UTC, которая выглядит следующим образом:

'2021-02-25 05:00:00.000 00:00'

посмотрите на 00:00 в конце

Пока все хорошо, проблема возникает, когда я запрашиваю базу данных, чтобы получить ту же дату, используя метод pymongo «find_one»

что я получаю, так это:

'2021-02-25 05:00:00-05:00'

посмотрите на -05:00 в конце

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

Кто-нибудь знает, что может произойти, если это какая-то ошибка в текущих версиях? Я использую python 3.8.5, pymongo 3.11.3 и mongodb 4.4.4

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

Комментарии:

1. Вы установили tz_aware флаг? Видишь pymongo.readthedocs.io/en/stable/api/bson /…

Ответ №1:

Если ваше приложение работает с несколькими часовыми поясами, вам следует настроить вашу систему (обычно предпочтительнее) или ваше приложение на использование UTC в качестве часового пояса.

Если вы сделаете это, у вас будет два часовых пояса, которые вам обычно нужно отслеживать: UTC, в котором хранится каждая временная метка, и местный часовой пояс, который используется для вывода и представления.

Если вы этого не сделаете (т. Е. Часовой пояс вашей системы и / или приложения отличается от UTC), вам необходимо отслеживать 3 часовых пояса и более 3 возможных комбинаций того, как все может пойти не так:

  • Часовой пояс, в котором находится ваш ввод (это системный часовой пояс или несистемное местное время?)
  • Когда вы сохраняете временную метку, указывается ли она в UTC, системное местное время или несистемное местное время?
  • и т.д.

Если ваше приложение работает с одним часовым поясом, И все ваше программное обеспечение создано для этого правильно, вы обычно можете считать, что все время указано по местному времени, и игнорировать часовые пояса.

Этот последний бит не всегда явно документирован. Например, в Ruby здесь описано поведение часового пояса базового драйвера, и в нем не говорится, что все времена возвращаются в локальном часовом поясе. Документация Mongoid содержит более обширный перечень часовых поясов, поскольку они явно настраиваются.

Для pymongo я предлагаю внимательно просмотреть всю документацию в поисках эквивалентных утверждений (и убедитесь, что вы также просматриваете документы по сериализации bson (de)), и в противном случае вам может потребоваться прочитать исходный код, чтобы определить поведение.

В любом случае, работать с несколькими часовыми поясами, когда часовой пояс вашей системы / приложения отличается от UTC, на самом деле сложнее, чем должно быть, и я не рекомендую это (если не для вас, то для тех, кому придется работать с вашим кодом после вас).

Комментарии:

1. Даже работая только с utc, у меня та же проблема, потому что pymongo возвращает даты по местному времени по умолчанию с вышеупомянутой ошибкой, я прочитал документацию по датам pymongo и многим сторонним источникам, но нигде я не нахожу информации об этом, наконец, я решил сохранить даты с использованием метки времени, котораяотлично подходит для моих нужд. спасибо за ответ

2. Согласно комментарию к вопросу, в pymongo ключ должен быть установлен tz_aware в соединении MongoClient при использовании pytz.

3. Если ваша система находится в UTC, не имеет значения, возвращает ли pymongo экземпляры naive или aware.