Преобразовать строку даты (из Gmail) в метку времени | Python - PullRequest
1 голос
/ 29 мая 2020

Я хочу сохранить дату получения электронных писем из учетной записи Gmail в базе данных временных рядов.

Проблема в том, что я не могу преобразовать строку, полученную из электронного письма, в метку времени.

Я пробовал это:

from datetime import datetime

date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)' 

date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')

print(date1_obj)

Но получил эту ошибку:

Traceback (most recent call last):
  File "/format_date.py", line 11, in <module>
    date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 359, in _strptime
    (data_string, format))
ValueError: time data 'Thu, 28 May 2020 08:15:58 -0700 (PDT)' does not match format '%a, %d %b %Y %H:%M:%S %z %Z'

Пробовал с или без заключения в скобки часового пояса. Читайте много, но ничего о том, как работать со строками даты, содержащими "(PDT)" или любые другие часовые пояса. Очень важно получить правильную дату ... Если я запустил тот же код без "(PDT)", я получил неправильное время (из-за моего местного времени).

Я знаю, что могу использовать строковые методы для манипулировать им и преобразовывать в правильное datetime, но я чувствую, что это было бы гибко.

Простите за мой ужасный английский sh.

Спасибо!

Ответы [ 4 ]

1 голос
/ 29 мая 2020

вы можете использовать dateutil s parser для анализа строки, автоматически определяя формат:

import dateutil
s = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)' 
dt = dateutil.parser.parse(s)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzoffset('PDT', -25200))
dt.utcoffset().total_seconds()
# -25200.0

Обратите внимание, что хотя часовому поясу присвоено имя ("PDT" ), это всего лишь смещение UT C 25200 с. Во многих случаях этого достаточно, по крайней мере, для преобразования в UT C.

Если вам нужен конкретный часовой пояс c (например, для учета переходов на летнее время и c.), Вы можете использовать отображение dict, которое вы передаете в dateutil.parser.parse как tzinfos:

tzmap = {'PDT': dateutil.tz.gettz('US/Pacific'),
         'PST': dateutil.tz.gettz('US/Pacific')}

dt = dateutil.parser.parse(s, tzinfos=tzmap)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzfile('US/Pacific'))
dt.utcoffset().total_seconds()
# -25200.0
0 голосов
/ 30 мая 2020

Что ж, после всех ваших ответов, которые были очень полезны, я наконец решил. 58 по местному времени, это именно то, что я искал.

Большое спасибо всем, кто нашел минутку, чтобы ответить.

0 голосов
/ 29 мая 2020

Если это не сработает, даже если вы заключите %Z в скобки, значит проблема в директиве% Z https://docs.python.org/3/library/time.html

Поддержка директивы% Z основывается на значениях, содержащихся в tzname и истинном дневном свете. Из-за этого он зависит от платформы c, за исключением распознавания UT C и GMT, которые всегда известны (и считаются часовыми поясами без перехода на летнее время).

Например, следующие результаты в ValueError для меня (в Европе)

date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PST)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)

В то время как с GMT выводится 2020-05-28 08:15:58-07:00

date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)

На основе вашего комментария под этим ответом вы могли разделите строку, если бит часового пояса не важен:

date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1.split(" (")[0], '%a, %d %b %Y %H:%M:%S %z')
0 голосов
/ 29 мая 2020

Закройте, вы забыли поставить скобку вокруг последней записи.

date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
...