2013-11-25 44 views
27

我試圖轉換到ISO使用datetime下面的代碼:ISO爲datetime對象: 'Z' 是一個糟糕的指令

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。

+2

相關:[將時間戳轉換爲datetime obj使用strptime](http://stackoverflow.com/q/12281975/4279) – jfs

回答

21

歡迎來到Python日期時間!處理日期和時間必然非常複雜,並且Python在這種情況下並沒有完全包含電池。你不能在strptime中使用%z,因爲Python沒有類來表示時區(你應該實現你自己的,或者更好的還包括一些其他的庫)。您想使用pytzpython-dateutil。欲瞭解更多詳情請看這裏:

Python strptime() and timezones?

+9

我的上帝的蟒蛇就像月亮的階段 - 本週我們會做到這一點這樣,下週誰在乎! –

+0

我不得不說'%z'的缺席的確令人非常失望...... –

14

與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問題:

如果蟒蛇2不支持,因爲底層strptime()實施,那麼%z一種可能的方式來解決您的問題是遷移到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(注意如何有一個在時區信息一:)。

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

請注意:因人而異,沒有支持。

+1

這真是太棒了!不需要第三方軟件包或自己的解析器代碼!我認爲很多人使用Django。 –

+0

這應該是正確的答案,因爲有人使用Django! –

+0

你有沒有Django這個問題的解決方案? –

相關問題