如何解析ISO 8601格式的日期和时间?
28 个回答
注意,在Python 2.6及以上版本和Python 3的版本中,%f这个字符可以用来显示微秒。
>>> datetime.datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
可以在这个链接查看相关问题:这里
自从Python 3.11版本开始,标准库里的 datetime.fromisoformat
函数可以处理任何有效的ISO 8601格式的输入。在之前的版本中,它只能解析特定的一部分格式,具体的注意事项可以查看文档。如果你使用的是Python 3.10或更早的版本,并且处理的字符串不在那个特定范围内(就像问题中提到的),可以看看其他答案中提到的来自标准库之外的函数。文档内容如下:
类方法
datetime.fromisoformat(date_string)
:这个函数会返回一个
datetime
对象,表示任何有效的ISO 8601格式的 date_string,但有以下几点例外:
- 时区偏移可以包含小数秒。
T
这个分隔符可以被任何单个的unicode字符替代。- 目前不支持序数日期。
- 不支持小数小时和分钟。
示例:
>>> from datetime import datetime >>> datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('20111104') datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('2011-11-04T00:05:23') datetime.datetime(2011, 11, 4, 0, 5, 23) >>> datetime.fromisoformat('2011-11-04T00:05:23Z') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc) >>> datetime.fromisoformat('20111104T000523') datetime.datetime(2011, 11, 4, 0, 5, 23) >>> datetime.fromisoformat('2011-W01-2T00:05:23.283') datetime.datetime(2011, 1, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc) >>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
在3.7版本中新增。
在3.11版本中更改:之前,这个方法只支持可以由date.isoformat()或datetime.isoformat()输出的格式。
isoparse
函数来自 python-dateutil
python-dateutil 这个包里有一个 dateutil.parser.isoparse
函数,它不仅可以解析像问题中提到的 RFC 3339 日期时间字符串,还能处理其他一些 ISO 8601 格式的日期和时间字符串,这些字符串可能不符合 RFC 3339 的要求,比如没有 UTC 偏移量的字符串,或者只表示日期的字符串。
>>> import dateutil.parser
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686Z') # RFC 3339 format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686') # ISO 8601 extended format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903T205635.450686') # ISO 8601 basic format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903') # ISO 8601 basic format, date only
datetime.datetime(2008, 9, 3, 0, 0)
python-dateutil 包里还有一个 dateutil.parser.parse
函数。跟 isoparse
比起来,它的要求可能没有那么严格,但这两个函数都比较宽容,会尽量理解你传入的字符串。如果你想避免任何误解,就需要使用比这两个函数更严格的工具。
与 Python 3.7+ 内置的 datetime.datetime.fromisoformat
的比较
dateutil.parser.isoparse
是一个完整的 ISO-8601 格式解析器,但在 Python 3.10 及之前的版本中,fromisoformat
是故意不支持的。到了 Python 3.11,fromisoformat
几乎支持所有有效的 ISO 8601 字符串。有关这一点的警告,请查看 fromisoformat
的文档。(可以参考 这个回答)。