Вопрос-Ответ

How do I translate an ISO 8601 datetime string into a Python datetime object? [duplicate]

Как мне перевести строку даты-времени ISO 8601 в объект даты-времени Python?

Я получаю строку даты-времени в формате типа "2009-05-28T16: 15: 00" (я полагаю, это ISO 8601). Один из хакерских вариантов, по-видимому, заключается в разборе строки с помощью time.strptime и передаче первых шести элементов кортежа в конструктор datetime, например:

datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])

Я не смог найти "более чистый" способ сделать это. Есть ли он?

Переведено автоматически
Ответ 1

Я предпочитаю использовать библиотеку dateutil для обработки часовых поясов и, как правило, для точного анализа даты. Если бы вы хотели получить ISO 8601 строку типа: 2010-05-08T23:41:54.000Z вам было бы интересно проанализировать ее с помощью strptime, особенно если вы заранее не знали, включен ли часовой пояс. pyiso8601 есть пара проблем (проверьте их отслеживание), с которыми я столкнулся во время использования, и он не обновлялся в течение нескольких лет. dateutil, напротив, был активен и работал у меня:

from dateutil import parser
yourdate = parser.parse(datestring)
Ответ 2

Поскольку в Python 3.7 нет внешних библиотек, вы можете использовать fromisoformat функцию из datetime модуля:

datetime.datetime.fromisoformat('2019-01-04T16:41:24+02:00')

Python 2 не поддерживает %z спецификатор формата, поэтому лучше явно использовать Zulu time везде, если это возможно:

datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")
Ответ 3

Поскольку ISO 8601, в основном, допускает наличие множества вариантов необязательных двоеточий и тире CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]. Если вы хотите использовать strptime, вам нужно сначала удалить эти варианты.

Цель состоит в том, чтобы сгенерировать объект даты-времени UTC.


Если вам просто нужен базовый регистр, который работает для UTC с суффиксом Z, например, 2016-06-29T19:36:29.3453Z:

datetime.datetime.strptime(timestamp.translate(None, ':-'), "%Y%m%dT%H%M%S.%fZ")

Если вы хотите обрабатывать смещения часовых поясов, например, 2016-06-29T19:36:29.3453-0400 или 2008-09-03T20:56:35.450686+05:00 используйте следующее. Они преобразуют все варианты во что-то без разделителей переменных, таких как 20080903T205635.450686+0500, что делает его более согласованным / простым для анализа.

import re
# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
datetime.datetime.strptime(conformed_timestamp, "%Y%m%dT%H%M%S.%f%z" )

Если ваша система не поддерживает %z директиву strptime (вы видите что-то вроде ValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'), то вам нужно вручную сместить время с Z (UTC). Примечание %z может не работать в вашей системе в версиях Python < 3, поскольку это зависит от поддержки библиотеки C, которая варьируется в зависимости от типа сборки system / Python (т.Е. Jython, Cython и т.д.).

import re
import datetime

# This regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)

# Split on the offset to remove it. Use a capture group to keep the delimiter
split_timestamp = re.split(r"([+|-])",conformed_timestamp)
main_timestamp = split_timestamp[0]
if len(split_timestamp) == 3:
sign = split_timestamp[1]
offset = split_timestamp[2]
else:
sign = None
offset = None

# Generate the datetime object without the offset at UTC time
output_datetime = datetime.datetime.strptime(main_timestamp +"Z", "%Y%m%dT%H%M%S.%fZ" )
if offset:
# Create timedelta based on offset
offset_delta = datetime.timedelta(hours=int(sign+offset[:-2]), minutes=int(sign+offset[-2:]))

# Offset datetime with timedelta
output_datetime = output_datetime + offset_delta
Ответ 4

Стрелка выглядит многообещающе для этого:

>>> import arrow
>>> arrow.get('2014-11-13T14:53:18.694072+00:00').datetime
datetime.datetime(2014, 11, 13, 14, 53, 18, 694072, tzinfo=tzoffset(None, 0))

Arrow - это библиотека Python, которая предоставляет разумный способ создания, управления, форматирования и преобразования дат и времени. Arrow прост, легковесен и в значительной степени вдохновлен moment.js и запросами.


python datetime