email.utils.parsedate_tz(date)
- используемая функция. Ниже приведены некоторые варианты.
Строка даты / времени электронной почты ( RFC 5322 , RFC 2822 , RFC 1123 ) для метки времени Unix в числах с плавающей запятой:
import email.utils
import calendar
def email_time_to_timestamp(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
return calendar.timegm(tt) - tt[9]
import time
print(time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(email_time_to_timestamp("Wed, 04 Jan 2017 09:55:45 -0800"))))
# 2017-01-04T17:55:45Z
Убедитесь, что вы не используете mktime
(который интерпретирует time_struct по местному времени вашего компьютера, а не по UTC); используйте вместо этого timegm
или mktime_tz
(но остерегайтесь предостережения для mktime_tz
в следующем абзаце).
Если вы уверены, что у вас Python версии 2.7.4, 3.2.4, 3.3 или новее, вы можете использовать email.utils.mktime_tz(tt)
вместо calendar.timegm(tt) - tt[9]
. До этого mktime_tz
выдавал неверное время при вызове во время перехода на летнее время в летнем часовом поясе ( ошибка 14653 ).
Спасибо @ j-f-sebastian за предостережений о mktime и mktime_tz .
Электронная строка даты / времени ( RFC 5322 , RFC 2822 , RFC 1123 ) для "осведомленности" datetime
на python 3.3:
На python 3.3 и выше используйте email.utils.parsedate_to_datetime
, который возвращает осведомленное datetime
с исходным смещением зоны:
import email.utils
email.utils.parsedate_to_datetime(s)
print(email.utils.parsedate_to_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T09:55:45-08:00
Предостережение: будет выброшено ValueError
, если время упадет на високосную секунду, например email.utils.parsedate_to_datetime("Sat, 31 Dec 2016 15:59:60 -0800")
.
Электронная строка даты / времени ( RFC 5322 , RFC 2822 , RFC 1123 ) для "осведомленности" datetime
в зоне UTC:
Это просто преобразуется в метку времени, а затем в UTC datetime
:
import email.utils
import calendar
import datetime
def email_time_to_utc_datetime(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
timestamp = calendar.timegm(tt) - tt[9]
return datetime.datetime.utcfromtimestamp(timestamp)
print(email_time_to_utc_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T17:55:45
Электронная строка даты / времени ( RFC 5322 , RFC 2822 , RFC 1123 ) для Python «в курсе» datetime
с исходным смещением:
До python 3.2 python не поставлялся с реализациями tzinfo, поэтому здесь приведен пример использования dateutil.tz.tzoffset
(pip install dateutil
):
import email.utils
import datetime
import dateutil.tz
def email_time_to_datetime(s):
tt = email.utils.parsedate_tz(s)
if tt is None: return None
tz = dateutil.tz.tzoffset("UTC%+02d%02d"%(tt[9]//60//60, tt[9]//60%60), tt[9])
return datetime.datetime(*tt[:5]+(min(tt[5], 59),), tzinfo=tz)
print(email_time_to_datetime("Wed, 04 Jan 2017 09:55:45 -0800").isoformat())
# 2017-01-04T09:55:45-08:00
Если вы используете python 3.2, вы можете использовать встроенную tzinfo
реализацию datetime.timezone
: tz = datetime.timezone(datetime.timedelta(seconds=tt[9]))
вместо стороннего dateutil.tz.tzoffset
.
Еще раз спасибо @ j-f-sebastian за примечание о зажиме високосной секунды .