datetime.datetime.utcnow()
Почему это datetime
не имеет никакой информации о часовом поясе, учитывая, что это явно UTC datetime
?
Я ожидаю, что это будет содержать tzinfo
.
datetime.datetime.utcnow()
Почему это datetime
не имеет никакой информации о часовом поясе, учитывая, что это явно UTC datetime
?
Я ожидаю, что это будет содержать tzinfo
.
Ответы:
Это означает, что это часовой пояс наивный, поэтому вы не можете использовать его с datetime.astimezone
Вы можете дать ему часовой пояс, как это
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
теперь вы можете менять часовые пояса
print(u.astimezone(pytz.timezone("America/New_York")))
Чтобы узнать текущее время в данном часовом поясе, вы можете передать tzinfo datetime.now()
напрямую:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Он работает для любого часового пояса, включая те, которые соблюдают переход на летнее время (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()
говорит:
Точную дату и время UTC можно узнать по телефону .
datetime.now
(
timezone.utc
)
Так что вы можете сделать:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
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
документации приведен пример .
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()
) ...
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.fromutc
pytz
это отличный ресурс. К тому времени, как я отредактировал свой ответ, вставив пример кода, кто-то другой уже предложил его, и я не хотел красть их гром.
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 для перекрестной совместимости.
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 !!
Жюльен Данджу написал хорошую статью, объясняющую, почему вы никогда не должны иметь дело с часовыми поясами . Выдержка:
Действительно, Python datetime API всегда возвращает незнакомые объекты datetime, что очень печально. В самом деле, как только вы получите один из этих объектов, вы не сможете узнать, что такое часовой пояс, поэтому эти объекты сами по себе довольно «бесполезны».
Увы, даже если вы можете использовать utcnow()
, вы все равно не увидите информацию о часовом поясе, как вы обнаружили.
Рекомендации:
Всегда используйте осведомленные
datetime
объекты, то есть с информацией о часовом поясе. Это гарантирует, что вы сможете сравнивать их напрямую (datetime
объекты со сведениями и объекты не сопоставимы) и будет правильно возвращать их пользователям. Используйте Pytz, чтобы иметь объекты часового пояса.Используйте ISO 8601 в качестве формата входной и выходной строки. Используйте
datetime.datetime.isoformat()
для возврата меток времени в виде строки, отформатированной с использованием этого формата, который включает информацию о часовом поясе.Если вам нужно проанализировать строки, содержащие метки времени в формате ISO 8601, вы можете положиться на них
iso8601
, которые возвращают метки времени с правильной информацией о часовом поясе. Это делает временные метки напрямую сопоставимыми.
Чтобы добавить timezone
информацию в Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (по умолчанию, 19 января 2017 г., 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Даты в формате UTC не нуждаются в информации о часовом поясе, поскольку они обозначены как UTC, что по определению означает, что они не имеют смещения.
pytz.utc
). Обратите внимание, что существует большая разница между значением, смещение которого от UTC неизвестно, и значением, для которого известно, что оно равно 0. Последнее utcnow()
должно возвращать IMO. Это соответствовало бы «Знающий объект используется для представления определенного момента времени, который не открыт для интерпретации» согласно документации.