使用最少的库解析任意 ISO 8601 时间戳

Python 对解析 ISO 8601 时间戳的支持有限。对于 strptime,你需要确切地知道它是什么格式。作为一个复杂因素,datetime 的字符串化是 ISO 8601 时间戳,空格作为分隔符和 6 位数分数:

str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555))
# '2016-07-22 09:25:59.555555'

但如果分数为 0,则不输出小数部分

str(datetime.datetime(2016, 7, 22, 9, 25, 59, 0))
# '2016-07-22 09:25:59'

但是这两种形式对于 strptime 需要不同的格式。此外,strptime' does not support at all parsing minute timezones that have ain it, thus2016-07-22 09:25:59 + 0300can be parsed, but the standard format2016-07-22 09:25:59 + 03:00`不能。

有一个名为 iso8601单文件库可以正确解析 ISO 8601 时间戳,只能解析它们。

它支持分数和时区,T 分隔符都具有单一功能:

import iso8601
iso8601.parse_date('2016-07-22 09:25:59')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22 09:25:59+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>)
iso8601.parse_date('2016-07-22 09:25:59Z')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22T09:25:59.000111+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00' ...>)

如果未设置时区,则 iso8601.parse_date 默认为 UTC。可以使用 default_zone 关键字参数更改默认区域。值得注意的是,如果这是 None 而不是默认值,那么那些没有显式时区的时间戳将作为天真的日期时间返回:

iso8601.parse_date('2016-07-22T09:25:59', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59)
iso8601.parse_date('2016-07-22T09:25:59Z', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)