如何将 ISO 8601 日期时间字符串转换为 Python 日期时间对象?
我得到一个格式类似于“2009-05-28T16:15:00”的日期时间字符串(我相信这是 ISO 8601)。 一个黑客选项似乎是使用 time.strptime 解析字符串并将元组的前六个元素传递到日期时间构造函数中,例如:
datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
我一直无法找到一种“更干净”的方法这样做的。 有吗?
I'm getting a datetime string in a format like "2009-05-28T16:15:00" (this is ISO 8601, I believe). One hackish option seems to be to parse the string using time.strptime
and passing the first six elements of the tuple into the datetime constructor, like:
datetime.datetime(*time.strptime("2007-03-04T21:08:12", "%Y-%m-%dT%H:%M:%S")[:6])
I haven't been able to find a "cleaner" way of doing this. Is there one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我更喜欢使用 dateutil 库进行时区处理和一般可靠的日期解析。 如果您要获得一个
ISO 8601
字符串,例如:2010-05-08T23:41:54.000Z
,您会很高兴用 strptime 解析它,特别是如果您事先不知道时区是否包括在内。pyiso8601
有几个我在使用过程中遇到的问题(检查他们的跟踪器),并且已经几年没有更新了。 相比之下,dateutil 一直很活跃并且为我工作:I prefer using the dateutil library for timezone handling and generally solid date parsing. If you were to get an
ISO 8601
string like:2010-05-08T23:41:54.000Z
you'd have a fun time parsing that with strptime, especially if you didn't know up front whether or not the timezone was included.pyiso8601
has a couple of issues (check their tracker) that I ran into during my usage and it hasn't been updated in a few years. dateutil, by contrast, has been active and worked for me:从 Python 3.7 开始,没有外部库,您可以使用
来自
函数/a> 模块:datetime
< 的 fromisoformatPython 2 不支持
%z
格式说明符,因此最好在任何地方显式使用 Zulu 时间(如果可能):Since Python 3.7 and no external libraries, you can use the
fromisoformat
function from thedatetime
module:Python 2 doesn't support the
%z
format specifier, so it's best to explicitly use Zulu time everywhere if possible:因为 ISO 8601 允许存在可选冒号和破折号的多种变体,基本上是
CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
。 如果您想使用 strptime,则需要首先删除这些变体。目标是生成 UTC 日期时间对象。
如果您只想要一个适用于带有 Z 后缀的 UTC 的基本情况,如
2016-06-29T19:36:29.3453Z
:如果您想处理
2016-06-29T19:36:29.3453-0400
或2008-09-03T20:56:35.450686+05:00
等时区偏移,请使用下列的。 这些会将所有变体转换为没有变量分隔符的内容,例如20080903T205635.450686+0500
使其更加一致/更易于解析。如果您的系统不支持
%z
strptime 指令(您会看到类似ValueError: 'z' is a baddirective in format '%Y%m%dT%H%M%S .%f%z'
) 那么您需要手动从Z
(UTC) 偏移时间。 注意%z
可能无法在您的 Python 版本版本的系统上运行。 3 因为它依赖于 C 库支持,而 C 库支持因系统/Python 构建类型而异(即 Jython 、Cython 等)。
Because ISO 8601 allows many variations of optional colons and dashes being present, basically
CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
. If you want to use strptime, you need to strip out those variations first.The goal is to generate a UTC datetime object.
If you just want a basic case that work for UTC with the Z suffix like
2016-06-29T19:36:29.3453Z
:If you want to handle timezone offsets like
2016-06-29T19:36:29.3453-0400
or2008-09-03T20:56:35.450686+05:00
use the following. These will convert all variations into something without variable delimiters like20080903T205635.450686+0500
making it more consistent/easier to parse.If your system does not support the
%z
strptime directive (you see something likeValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'
) then you need to manually offset the time fromZ
(UTC). Note%z
may not work on your system in Python versions < 3 as it depended on the C library support which varies across system/Python build type (i.e., Jython, Cython, etc.).箭头 看起来很有希望:
Arrow looks promising for this:
您应该密切关注时区信息,因为在比较非 tz 感知的日期时间与 tz 感知的日期时间时可能会遇到麻烦。
最好始终让他们了解 tz(即使仅作为 UTC),除非您真的知道为什么这样做没有任何用处。
You should keep an eye on the timezone information, as you might get into trouble when comparing non-tz-aware datetimes with tz-aware ones.
It's probably the best to always make them tz-aware (even if only as UTC), unless you really know why it wouldn't be of any use to do so.
我还没有尝试过,但是 pyiso8601 承诺支持这一点。
I haven't tried it yet, but pyiso8601 promises to support this.
这还包括毫秒和时区。
如果时间是“2012-09-30T15:31:50.262-08:00”,这将转换为纪元时间。
This also includes the milliseconds and time zone.
If the time is '2012-09-30T15:31:50.262-08:00', this will convert into epoch time.
两种方式:
纪元到 ISO 时间:
ISO 时间到纪元:
Both ways:
Epoch to ISO time:
ISO time to Epoch:
Isodate 似乎拥有最完整的支持。
Isodate seems to have the most complete support.
aniso8601 应该可以处理这个问题。 它还理解时区、Python 2 和 Python 3,并且对 ISO 8601 的其余部分有合理的覆盖,如果您需要它。
aniso8601 should handle this. It also understands timezones, Python 2 and Python 3, and it has a reasonable coverage of the rest of ISO 8601, should you ever need it.
这是进行此类转换的超级简单方法。
无需解析或额外的库。
它干净、简单、快速。
Here is a super simple way to do these kind of conversions.
No parsing, or extra libraries required.
It is clean, simple, and fast.