Преобразование строки UTC datetime в локальное datetime
Мне никогда не приходилось преобразовывать время в UTC и обратно. Недавно поступил запрос на то, чтобы мое приложение учитывало часовой пояс, и я бегал по кругу. Много информации о преобразовании местного времени в UTC, которое я нашел довольно элементарным (возможно, я и это делаю неправильно), но я не могу найти никакой информации о том, как легко преобразовать время UTC в часовой пояс конечного пользователя.
В двух словах, и приложение Android отправляет мне (приложение appengine) данные, а внутри этих данных находится временная метка. Чтобы сохранить эту временную метку в соответствии со временем utc, я использую:
datetime.utcfromtimestamp(timestamp)
Кажется, это работает. Когда мое приложение сохраняет данные, они сохраняются на 5 часов вперед (у меня EST -5)
Данные хранятся в BigTable appengine, и при извлечении они выдаются в виде строки, подобной следующей:
"2011-01-21 02:37:21"
Как мне преобразовать эту строку в дату и время в правильном часовом поясе пользователя?
Кроме того, каково рекомендуемое хранилище для информации о часовом поясе пользователя? (Как вы обычно храните информацию о времени, например: "-5: 00" или "EST" и т.д. и т.п.?) Я уверен, что ответ на мой первый вопрос может содержать параметр, который отвечает на второй.
Переведено автоматически
Ответ 1
Если вы не хотите предоставлять свои собственные tzinfo объекты, ознакомьтесь с библиотекой python-dateutil. Он предоставляет tzinfo реализации поверх базы данных zoneinfo (Olson), так что вы можете ссылаться на правила часовых поясов с помощью несколько канонического имени.
from datetime import datetime from dateutil import tz
Это позволяет избежать проблем с синхронизацией в примере DelboyJay. И меньших проблем с синхронизацией в поправке Эрика ван Остена.
В качестве интересной сноски, вычисленное выше смещение часового пояса может отличаться от следующего, казалось бы, эквивалентного выражения, вероятно, из-за изменений в правилах перехода на летнее время:
Обновление: Недостатком этого фрагмента является использование смещения UTC текущего времени, которое может отличаться от смещения UTC входного datetime . Другое решение смотрите в комментариях к этому ответу.
Чтобы обойти различия во времени, возьмите время эпохи из прошедшего времени. Вот что я делаю:
Смотрите документацию по datetime по объектам tzinfo. Вы должны реализовать часовые пояса, которые хотите поддерживать самостоятельно. Примеры приведены в нижней части документации.
t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S') t = t.replace(tzinfo=GMT) print t print t.astimezone(EST)
Вывод
01/22/201121:52:09 01/22/201121:52:09 GMT 01/22/201116:52:09 EST 2011-01-21 02:37:21+00:00 2011-01-2021:37:21-05:00a
Ответ 4
Если вы хотите получить правильный результат даже для времени, соответствующего неоднозначному местному времени (например, при переходе на летнее время), и / или локальное смещение utc отличается в разное время в вашем местном часовом поясе, тогда используйте pytz часовые пояса: