#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.