【问题标题】:How to parse timezone with colon如何用冒号解析时区
【发布时间】:2015-09-09 01:01:21
【问题描述】:

有没有办法用datetime.strptime 解析“+00:00”格式的时区?例如:

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> datetime.strptime("12:34:56+0000", "%X%z")
datetime.datetime(1900, 1, 1, 12, 34, 56, tzinfo=datetime.timezone.utc)
>>> datetime.strptime("12:34:56+00:00", "%X%z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python34\lib\_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "C:\Python34\lib\_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data '12:34:56+00:00' does not match format '%X%z'

有什么想法吗?

【问题讨论】:

标签: python string datetime strptime


【解决方案1】:

目前,对此没有治愈方法,这里有解释:https://bugs.python.org/issue15873 更准确地说,这里是:https://bugs.python.org/msg169952。 但是你可以通过这种方式覆盖这个问题:

from datetime import datetime
d = "2015-04-30T23:59:59+00:00"
if ":" == d[-3:-2]:
    d = d[:-3]+d[-2:]
print(datetime.strptime(d, "%Y-%m-%dT%H:%M:%S%z"))

【讨论】:

  • 为什么不只是if ":" == d[-3]:
  • 为什么要使用 if?不应该:总是在同一个位置?
【解决方案2】:

改编自被拒绝的编辑:

Python >= 3.7:

from datetime import datetime
d = "2019-12-25T23:59:59+00:00"
print(datetime.strptime(d, "%Y-%m-%dT%H:%M:%S%z"))

在 3.7 版中更改:当 %z 指令提供给 strptime() 方法时,UTC 偏移量可以使用冒号作为小时、分钟和秒之间的分隔符。例如,“+01:00:00”将被解析为一小时的偏移量。此外,提供“Z”与“+00:00”相同。

https://docs.python.org/3.7/library/datetime.html

Python

没有内置方式,但最好的解决方案是:

from datetime import datetime
d = "2019-12-25T23:59:59+00:00"
if ":" == d[-3]:
    d = d[:-3]+d[-2:]
print(datetime.strptime(d, "%Y-%m-%dT%H:%M:%S%z"))

说明: https://bugs.python.org/issue15873 https://bugs.python.org/msg169952

【讨论】:

    【解决方案3】:

    另一种解决方案是使用dateutil 库:

    from dateutil import parser
    
    mystr = '2015-04-30T23:59:59+00:00'
    
    x = parser.parse(mystr)
    
    # 2015-04-30 23:59:59+00:00
    

    【讨论】:

      【解决方案4】:

      老问题,但我想我会添加这个。

      从 3.7 开始,您可以使用time.fromisoformat()

      from datetime import time
      iso_datetime_string = "2021-01-01T00:00:00+00:00"
      print(time.fromisoformat(iso_datetime_string))
      

      题外话,但可能对其他人有用:如果您尝试做与 OP 相反的操作,也没有本地方法可以通过 .strftime() 转换日期时间对象,zulu 偏移格式为“+00 :00" (有 %z 但这会给你“+0000”)。我找到的解决方案是datetime.isoformat(),而且这个解决方案在 3.7 之前也可以使用

      【讨论】: