42

我正在尝试将 ISO 转换为datetime使用以下代码:

dt = datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00",
                                "%Y-%m-%dT%H:%M:%S.%f%z")

我收到以下错误:

'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z'

将上述格式的 ISO 字符串转换为datetime对象的最佳方法是什么?我正在使用 Python 2.7.6 版。

4

2 回答 2

27

欢迎来到 Python 日期时间!处理日期和时间必然很复杂,并且 Python 并没有完全配备包含在这种情况下的电池。您不能使用%zin,strptime因为 Python 没有代表时区的类(您应该实现自己的,或者最好包含一些其他库)。

您想使用pytzpython-dateutil。有关更多详细信息,请参见此处:

Python strptime() 和时区?

于 2013-11-25T13:47:18.763 回答
24

python 2.7的问题

我在解析提交日期时遇到了类似的问题,其输出git log --date=iso8601实际上不是 ISO8601 格式(因此--date=iso8601-strict在更高版本中添加了)。

>>> import datetime, sys
>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%M:%S.%f%z'
>>> sys.version
'2.7.10 (default, Feb  7 2017, 00:08:15) \n[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]'

python 3的问题:

%z如果由于底层实现而导致python 2 不支持strptime(),那么解决问题的一种可能方法是迁移到 python 3。但这对我不起作用:

>>> import datetime, sys
>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+01:00", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 565, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_strptime.py", line 362, in _strptime
    (data_string, format))
ValueError: time data '2013-07-23T15:10:59.342107+01:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
>>> sys.version
'3.6.3 (v3.6.3:2c5fed86e0, Oct  3 2017, 00:32:08) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]'

问题是因为不是严格的 ISO8601(请注意:时区信息中的 a )。

>>> datetime.datetime.strptime("2013-07-23T15:10:59.342107+0100", "%Y-%m-%dT%H:%M:%S.%f%z")
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=datetime.timezone(datetime.timedelta(0, 3600)))

使用 django 和 pytz 的解决方案:

由于我正在使用django,我可以利用那里的实用程序。

https://github.com/django/django/blob/master/django/utils/dateparse.py

>>> from django.utils.dateparse import parse_datetime
>>> parse_datetime('2013-07-23T15:10:59.342107+01:00')
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)

而不是strptime你可以使用你自己的正则表达式。

请注意,django 确实pytz在后台使用了utc单例。

没有 django & pytz 的解决方案:

如果您想要一个快速而肮脏的解决方案,您可以使用类似的东西django而不需要所有要求。

https://gist.github.com/dnozay/3cd554a818ed768bff804bc04484905d

>>> from datetime_z import parse_datetime
>>> parse_datetime("2013-07-23T15:10:59.342107+01:00")
datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)

请注意:YMMV,没有支持。

于 2015-01-07T22:07:39.410 回答