Datetime strptime issue with a timezone offset with colons

笑着哭i 提交于 2020-07-07 06:04:08

问题


Currently we are working on an application which is trying to calculate the travel time of a route from a to b, using the 2.db.transport.rest API.

Unfortunatly we are receiving timestamps with a timezone offset from that API, such as +01:00. What we need is a timezone offset without the :, so +0100.

The following example gives an error on Linux, using Python 3.6.7:

from datetime import datetime
datetimestring = "2019-01-19T15:13:00.000+01:00"
datetime.strptime(datetimestring, '%Y-%m-%dT%H:%M:%S.%f%z')

This example code produces this exception:

ValueError: time data '2019-01-19T15:13:00.000+01:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'

If we remove the : from the input string it works, no exception is thrown.

The code also works when we run this on Windows, on Python 3.7.2.

Could it be due to the different Python versions? How can we parse or convert this without error?


回答1:


Yes, this is a version problem. You are relying on a new feature introduced in Python 3.7

From the datetime.strptime() documentation, 6th footnote:

Changed in version 3.7: When the %z directive is provided to the strptime() method, the UTC offsets can have a colon as a separator between hours, minutes and seconds. For example, '+01:00:00' will be parsed as an offset of one hour.

If you can't upgrade to Python 3.7 everywhere, then you could just remove those colons with some preprocessing:

import re

datetimestring = re.sub(r'([-+]\d{2}):(\d{2})(?:(\d{2}))?$', r'\1\2\3', datetimestring)

The regex removes the colons from any HH:MM or HH:MM:SS offset (appearing at the end of a string and preceded by - or +):

Demo:

>>> import re
>>> from datetime import datetime
>>> datetimestring = "2019-01-19T15:13:00.000+01:00"
>>> corrected = re.sub(r'([-+]\d{2}):(\d{2})(?:(\d{2}))?$', r'\1\2\3', datetimestring)
>>> corrected
'2019-01-19T15:13:00.000+0100'
>>> datetime.strptime(corrected, '%Y-%m-%dT%H:%M:%S.%f%z')
datetime.datetime(2019, 1, 19, 15, 13, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))

If you were to upgrade to Python 3.7 everywhere, you could drop the strptime() parsing altogether and simply use the dedicated datetime.fromisoformat() method; it can parse your input directly.

>>> datetime.fromisoformat(datetimestring)
datetime.datetime(2019, 1, 19, 15, 13, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))


来源:https://stackoverflow.com/questions/54268458/datetime-strptime-issue-with-a-timezone-offset-with-colons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!