Несколько ответов здесь предложить с использованием datetime.datetime.strptime
для анализа дат времени RFC 3339 или ISO 8601 с часовые пояса, как показано в вопросе:
2008-09-03T20:56:35.450686Z
Это плохая идея.
Предполагая, что вы хотите поддерживать полный формат RFC 3339, включая поддержку смещений UTC, отличных от нуля, код, предлагаемый в этих ответах, не работает. Действительно, не может работать, потому что синтаксический анализ RFC 3339 с использованием strptime
невозможен. Строки формата, используемые модулем datetime в Python, не могут описать синтаксис RFC 3339.
Проблема в смещениях UTC. RFC 3339 Интернет-формат даты / времени требует, чтобы каждая дата-время включало смещение UTC, и чтобы эти смещения могли быть либо Z
(сокращение от "времени Зулуса"), либо +HH:MM
или * Формат 1026 *, например +05:00
или -10:30
.
Следовательно, все это действительные даты и время RFC 3339:
2008-09-03T20:56:35.450686Z
2008-09-03T20:56:35.450686+05:00
2008-09-03T20:56:35.450686-10:30
Увы, строки формата, используемые strptime
и strftime
, не имеют директив, соответствующих смещениям UTC в формате RFC 3339. Полный список директив, которые они поддерживают, можно найти в https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior,, и единственная директива смещения UTC, включенная в список, является %z
:
% г * * тысяча пятьдесят-два
Смещение UTC в форме + ЧЧММ или -ЧЧММ (пустая строка, если объект наивный).
Пример: (пусто), +0000, -0400, + 1030
Это не соответствует формату смещения RFC 3339, и действительно, если мы попытаемся использовать %z
в строке формата и проанализировать дату RFC 3339, у нас не получится:
>>> <b><i>from datetime import datetime</i></b>
>>> <b><i>datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%f%z")</b></i>
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686Z' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
>>> <b><i>datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%f%z")</i></b>
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
(На самом деле, вышеописанное - это то, что вы увидите в Python 3. В Python 2 мы потерпим неудачу по еще более простой причине: strptime
не реализует директиву %z
в все в Python 2 .)
Несколько ответов здесь, которые рекомендуют strptime
, позволяют обойти это путем включения литерала Z
в их строку формата, которая соответствует Z
из строки datetime примера автора вопроса (и отбрасывает его, создавая datetime
объект без часового пояса):
>>> <b><i>datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")</i></b>
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
Так как при этом отбрасывается информация о часовом поясе, которая была включена в исходную строку даты и времени, сомнительно, должны ли мы рассматривать даже этот результат как правильный. Но что еще более важно, поскольку этот подход включает в себя жесткое кодирование определенного смещения UTC в строку формата , он будет подавлять момент, когда он пытается проанализировать любое время RFC 3339 с другим смещением UTC:
>>> <b><i>datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%fZ")</i></b>
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'
Если вы не уверены , что вам нужно только поддерживать дату и время RFC 3339 по времени Зулу, а не время с другими смещениями часового пояса, не используйте strptime
. Вместо этого используйте один из многих других подходов, описанных в ответах.