Python ISO 到日期时间对象:'z' 是一个错误的指令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20194496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:49:34  来源:igfitidea点击:

ISO to datetime object: 'z' is a bad directive

pythondatetimeisorfc3339

提问by user2667326

I am trying to convert ISO to datetimeusing the code below:

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

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

and I'm getting the error below:

我收到以下错误:

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

What is the best way to convert an ISO string of above the format to a datetimeobject? I'm using Python version 2.7.6.

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

回答by Max

Welcome to Python datetime! Dealing with dates and times is necessarily complex, and Python doesn't come fully with batteries included in this case. You can't use %zin strptimebecause Python has no classes to represent timezones (you are supposed to implement your own, or better yet include some other libraries).

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

You want to use pytzand python-dateutil. For more details see here:

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

Python strptime() and timezones?

Python strptime() 和时区?

回答by dnozay

problem with python 2.7

python 2.7的问题

I have had a similar problem parsing commit dates from the output of git log --date=iso8601which actually isn't the ISO8601 format (hence the addition of --date=iso8601-strictin a later version).

我在解析输出中的提交日期时遇到了类似的问题,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)]'

problem with python 3:

python 3的问题:

If python 2 does not support %zbecause of the underlying strptime()implementation, then a possible way to fix your issue is to migrate to python 3. But it didn't work for me:

如果%z由于底层strptime()实现而不支持 python 2 ,那么解决问题的一种可能方法是迁移到 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)]'

The problem is because is not strictly ISO8601 (note how there was a :in the timezone info).

问题是因为不是严格的 ISO8601(注意:时区信息中是如何存在的)。

>>> 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)))

solution with django & pytz:

django & pytz 的解决方案:

Since I am using djangoI can leverage the utilities there.

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

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

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)

Instead of strptimeyou could use your own regular expression.

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

Please note that django does use pytzunder the hood for things like the utcsingleton.

请注意,django 确实pytz在底层使用了诸如utc单例之类的东西。

solution without django & pytz:

没有 django 和 pytz 的解决方案:

If you want a quick and dirty solution, you can use something similar to djangowithout all the requirements.

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

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

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)

Please note: YMMV, there is no support.

请注意:YMMV,不支持。