Может ли PyYAML анализировать даты iso8601?

Согласно спецификации YAML, даты iso8601 с часовыми поясами должны распознаваться. Однако, пытаясь разобрать их с помощью PyYAML 3.10 (в Windows 7 с ActivePython 2.7.2.5), я получаю наивные даты:

In [7]: yaml.load("2001-12-14t21:59:43.10-05:00")
Out[7]: datetime.datetime(2001, 12, 15, 2, 59, 43, 100000)

In [8]: yaml.load("2001-12-14 21:59:43.10 -5")
Out[8]: datetime.datetime(2001, 12, 15, 2, 59, 43, 100000)

(Первый формат - это строгий iso8601, а второй - «расслабленный» формат; примеры взяты непосредственно из спецификации YAML.)

Это ожидаемое поведение или мой PyYaml работает некорректно?


person Charles Roper    schedule 08.11.2012    source источник


Ответы (3)


Это исправлено в pyyaml ​​5.3 (Github Pull Request)

>>> yaml.safe_load('2020-12-17t14:40:00+02:00')
datetime.datetime(2020, 12, 17, 14, 40, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))
person Gary van der Merwe    schedule 17.12.2020

Если вам не нравится поведение по умолчанию (наивный utc datetime, потеря смещения utc), вы можете предоставить свой собственный конструктор:

import dateutil.parser
import yaml

def timestamp_constructor(loader, node):
    return dateutil.parser.parse(node.value)
yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)

print(repr(yaml.load("2001-12-14T21:59:43.10-05:00")))
# -> datetime.datetime(2001, 12, 14, 21, 59, 43, 100000, tzinfo=tzoffset(None, -18000))
person jfs    schedule 08.11.2012

Это также влияет на Django при загрузке фикстур базы данных из файлов YAML. Существует обходной путь, специфичный для Django; см .: Loaddata не обрабатывает временные метки и часовые пояса должным образом

person Christopher Beland    schedule 08.01.2019