Он работает для любого часового пояса, включая те, которые соблюдают переход на летнее время (DST), т. Е. Он работает для часовых поясов, которые могут иметь разные смещения utc в разное время (нефиксированное смещение utc). Не используйте tz.localize(datetime.now())- он может потерпеть неудачу во время перехода в конце летнего времени, когда местное время неоднозначно.
Но нет веских причин для того, чтобы он был наивным с часовым поясом - он определен как UTC. Зачем вам нужно искать стороннюю библиотеку, чтобы она работала правильно?
Марк Рэнсом
4
Я согласен; для меня «наивные» времена совершенно бесполезны. В настоящее время в списке python обсуждается вопрос о добавлении pytz в stdlib; проблема не в лицензировании, а в том, что данные о часовых поясах обновляются так часто (чего не может быть сам Python). Кроме того, pytz не реализует интерфейс tzinfo ожидаемым образом, поэтому вы можете получить ошибки, если попытаетесь использовать некоторые из часовых поясов города astimezone. Таким образом, datetime не только не имеет собственных часовых поясов, но и единственная широко распространенная реализация tzinfo не соответствует предполагаемому стандарту.
2010 года
5
@bobince Почему у вас не работают pytz и стандартные библиотеки datetime? Ядро Python и pytz, развивающиеся как независимые проекты, уменьшают логистическую сложность для основной команды. Да, снижение сложности для основной команды Python увеличивает сложность для всех пользователей Python, которым необходимо иметь дело с часовыми поясами, но я верю, что они приняли это решение по уважительной причине. Правило «Стандартная библиотека не имеет экземпляров tzinfo ...» прекрасно, потому что просто, зачем делать исключение здесь?
Дерек Лиц
15
Как насчет простоu=datetime.now(pytz.utc)
Крейг МакКуин
4
@bain: не использовать tz.localize(datetime.now()); используйте datetime.now(tz)вместо этого.
Что предпочтительнее? datetime.now(timezone.utc)или datetime.utcnow(timezone.utc)?
Джесси Уэбб
8
datetime.utcnow()не принимает аргументов Так и должно быть datetime.now(timezone.utc).
Крейг МакКуин
1
datetime.now()вернет время машины, но datetime.utcnow()вернет фактическое время UTC.
Бабу
13
@Babu: datetime.utcnow()не tzinfoуказывает, что это UTC. Но datetime.now(datetime.timezone.utc)возвращает время UTC сtzinfo установленным.
Крейг МакКуин
@CraigMcQueen Итак, если мы передадим tzобъект в конструктор now, он вернет время этого часового пояса? Хорошо! Спасибо за указание.
Бабу
71
Стандартные библиотеки Python не включают в себя классы tzinfo (но см. Pep 431 ). Я могу только догадываться по причинам. Лично я думаю, что было ошибкой не включать класс tzinfo для UTC, потому что он достаточно спорный, чтобы иметь стандартную реализацию.
Редактировать: Хотя в библиотеке нет реализации, в tzinfoдокументации приведен пример .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)# A UTC class.class UTC(tzinfo):"""UTC"""def utcoffset(self, dt):return ZERO
def tzname(self, dt):return"UTC"def dst(self, dt):return ZERO
utc = UTC()
Чтобы использовать его, чтобы получить текущее время как осведомленный объект datetime:
from datetime import datetime
now = datetime.now(utc)
Есть datetime.timezone.utcв Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Пойди разберись, почему этот класс не был предоставлен в первую очередь (и, что более важно, использовался для datetimeобъектов, созданных utcnow()) ...
Андре Карон
17
Объект часового пояса timezone.utcбыл наконец добавлен в Python 3.2. Для обратной совместимости, utcnow()все еще возвращает объект времени без часового пояса, но вы можете получить то, что вы хотите, позвонив now(timezone.utc).
mhsmith
4
@rgove, это тот вид исправления ошибок, который должен был быть честной игрой для Python 3. Им не стоило беспокоиться об обратной совместимости. За последние несколько дней я прочитал еще один пример - structмодуль будет выполнять автоматическое преобразование из Unicode в bytestring, и окончательное решение состояло в том, чтобы нарушить совместимость с более ранними версиями Python 3, чтобы предотвратить дальнейшее неправильное решение.
@LS да, pytzэто отличный ресурс. К тому времени, как я отредактировал свой ответ, вставив пример кода, кто-то другой уже предложил его, и я не хотел красть их гром.
Марк Рэнсом
20
pytzМодуль является одним из вариантов, и есть другой python-dateutil, который , хотя и является также пакет третьей партии, уже могут быть доступны в зависимости от других зависимостей и операционной системы.
Я просто хотел включить эту методологию для справки - если вы уже установили python-dateutilдля других целей, вы можете использовать ее tzinfoвместо дублирования сpytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Я склонен согласиться, что звонки utcnowдолжны включать информацию о часовом поясе UTC. Я подозреваю, что это не включено, потому что собственная библиотека datetime по умолчанию наивна datetime для перекрестной совместимости.
Я использовал вызов datetime.datetime.utcfromtimestamp () и мне нужно было добавить tzinfo. У меня сработало второе решение: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Поскольку моя программа уже импортирования dateutilдля dateutil.parser, мне понравилось это решение лучше. Это было так просто , как: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). Viola !!
Действительно, Python datetime API всегда возвращает незнакомые объекты datetime, что очень печально. В самом деле, как только вы получите один из этих объектов, вы не сможете узнать, что такое часовой пояс, поэтому эти объекты сами по себе довольно «бесполезны».
Увы, даже если вы можете использовать utcnow(), вы все равно не увидите информацию о часовом поясе, как вы обнаружили.
Рекомендации:
Всегда используйте осведомленные datetimeобъекты, то есть с информацией о часовом поясе. Это гарантирует, что вы сможете сравнивать их напрямую ( datetime
объекты со сведениями и объекты не сопоставимы) и будет правильно возвращать их пользователям. Используйте Pytz, чтобы иметь объекты часового пояса.
Используйте ISO 8601 в качестве формата входной и выходной строки. Используйте datetime.datetime.isoformat()для возврата меток времени в виде строки, отформатированной с использованием этого формата, который включает информацию о часовом поясе.
Если вам нужно проанализировать строки, содержащие метки времени в формате ISO 8601, вы можете положиться на них iso8601, которые возвращают метки времени с правильной информацией о часовом поясе. Это делает временные метки напрямую сопоставимыми.
Это слегка вводящая в заблуждение рекомендация. Эмпирическое правило: никогда не работайте с часовыми поясами. Всегда сохраняйте и передавайте незанятые объекты (объекты эпохи). Часовой пояс следует рассчитывать только во время представления в пользовательском интерфейсе
17
1
Похоже, это уже вполне соответствует мысли Жюльена. Какие из его конкретных рекомендаций (как указано выше) вводят в заблуждение?
Джо д'Андреа
10
Чтобы добавить timezoneинформацию в Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
Даты в формате UTC не нуждаются в информации о часовом поясе, поскольку они обозначены как UTC, что по определению означает, что они не имеют смещения.
Насколько я могу судить из docs.python.org/library/datetime.html , дата- время без tzinfo - это та, где часовой пояс не указан. Здесь временная зона была задана, поэтому логически она должна присутствовать. Существует большая разница между датой / временем без ассоциированного часового пояса и датой, которая определенно указана в UTC. (В идеале это должны быть разные типы IMO, но это другое дело ...)
Джон Скит
@JonSkeet Я думаю, вы упускаете из виду Игнасио, что UTC не является часовым поясом. Удивительно, что этот ответ набрал -9 баллов, когда я набираю это ...
CS
3
@CS: Ну, Игнасио никогда не заявлял об этом ... и, хотя, строго говоря, UTC не является часовым поясом, он обычно рассматривается как один, чтобы значительно упростить жизнь (в том числе в Python, например, с помощью pytz.utc). Обратите внимание, что существует большая разница между значением, смещение которого от UTC неизвестно, и значением, для которого известно, что оно равно 0. Последнее utcnow()должно возвращать IMO. Это соответствовало бы «Знающий объект используется для представления определенного момента времени, который не открыт для интерпретации» согласно документации.
Ответы:
Это означает, что это часовой пояс наивный, поэтому вы не можете использовать его с
datetime.astimezone
Вы можете дать ему часовой пояс, как это
теперь вы можете менять часовые пояса
Чтобы узнать текущее время в данном часовом поясе, вы можете передать tzinfo
datetime.now()
напрямую:Он работает для любого часового пояса, включая те, которые соблюдают переход на летнее время (DST), т. Е. Он работает для часовых поясов, которые могут иметь разные смещения utc в разное время (нефиксированное смещение utc). Не используйте
tz.localize(datetime.now())
- он может потерпеть неудачу во время перехода в конце летнего времени, когда местное время неоднозначно.источник
astimezone
. Таким образом, datetime не только не имеет собственных часовых поясов, но и единственная широко распространенная реализация tzinfo не соответствует предполагаемому стандарту.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; используйтеdatetime.now(tz)
вместо этого.Обратите внимание, что для Python 3.2 и далее,
datetime
модуль содержитdatetime.timezone
. Документация дляdatetime.utcnow()
говорит:Так что вы можете сделать:
источник
datetime.now(timezone.utc)
илиdatetime.utcnow(timezone.utc)
?datetime.utcnow()
не принимает аргументов Так и должно бытьdatetime.now(timezone.utc)
.datetime.now()
вернет время машины, ноdatetime.utcnow()
вернет фактическое время UTC.datetime.utcnow()
неtzinfo
указывает, что это UTC. Ноdatetime.now(datetime.timezone.utc)
возвращает время UTC сtzinfo
установленным.tz
объект в конструктор now, он вернет время этого часового пояса? Хорошо! Спасибо за указание.Стандартные библиотеки Python не включают в себя классы tzinfo (но см. Pep 431 ). Я могу только догадываться по причинам. Лично я думаю, что было ошибкой не включать класс tzinfo для UTC, потому что он достаточно спорный, чтобы иметь стандартную реализацию.
Редактировать: Хотя в библиотеке нет реализации, в
tzinfo
документации приведен пример .Чтобы использовать его, чтобы получить текущее время как осведомленный объект datetime:
Есть
datetime.timezone.utc
в Python 3.2+:источник
datetime
объектов, созданныхutcnow()
) ...timezone.utc
был наконец добавлен в Python 3.2. Для обратной совместимости,utcnow()
все еще возвращает объект времени без часового пояса, но вы можете получить то, что вы хотите, позвонивnow(timezone.utc)
.struct
модуль будет выполнять автоматическое преобразование из Unicode в bytestring, и окончательное решение состояло в том, чтобы нарушить совместимость с более ранними версиями Python 3, чтобы предотвратить дальнейшее неправильное решение.tzinfo
документации Python есть примеры кода для его реализации, но они не включают эту функциональность в самой datetime! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
это отличный ресурс. К тому времени, как я отредактировал свой ответ, вставив пример кода, кто-то другой уже предложил его, и я не хотел красть их гром.pytz
Модуль является одним из вариантов, и есть другойpython-dateutil
, который , хотя и является также пакет третьей партии, уже могут быть доступны в зависимости от других зависимостей и операционной системы.Я просто хотел включить эту методологию для справки - если вы уже установили
python-dateutil
для других целей, вы можете использовать ееtzinfo
вместо дублирования сpytz
Я склонен согласиться, что звонки
utcnow
должны включать информацию о часовом поясе UTC. Я подозреваю, что это не включено, потому что собственная библиотека datetime по умолчанию наивна datetime для перекрестной совместимости.источник
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
этого всегда работает;datetime.now(dateutil.tz.tzlocal())
может потерпеть неудачу во время переходов DST . PEP 495 - устранение неоднозначности по местному времени может улучшитьdateutil
ситуацию в будущем.utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(примечание:dateutil
с нефиксированным смещением utc (например,dateutil.tz.tzlocal()
) здесь может произойти сбой , вместо этого используйте решение наpytz
основе ).dateutil
дляdateutil.parser
, мне понравилось это решение лучше. Это было так просто , как:utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola !!Жюльен Данджу написал хорошую статью, объясняющую, почему вы никогда не должны иметь дело с часовыми поясами . Выдержка:
Увы, даже если вы можете использовать
utcnow()
, вы все равно не увидите информацию о часовом поясе, как вы обнаружили.Рекомендации:
источник
Чтобы добавить
timezone
информацию в Python 3.2+источник
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (по умолчанию, 19 января 2017 г., 14:48:08)источник
Даты в формате UTC не нуждаются в информации о часовом поясе, поскольку они обозначены как UTC, что по определению означает, что они не имеют смещения.
источник
pytz.utc
). Обратите внимание, что существует большая разница между значением, смещение которого от UTC неизвестно, и значением, для которого известно, что оно равно 0. Последнееutcnow()
должно возвращать IMO. Это соответствовало бы «Знающий объект используется для представления определенного момента времени, который не открыт для интерпретации» согласно документации.