带有冒号的时区偏移的日期时间 strptime 问题 [英] Datetime strptime issue with a timezone offset with colons

查看:62
本文介绍了带有冒号的时区偏移的日期时间 strptime 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我们正在开发一个应用程序,该应用程序尝试使用 2.db.transport.rest API 计算从 a 到 b 的路线的旅行时间.

不幸的是,我们正在从该 API 接收带有时区偏移的时间戳,例如 +01:00.我们需要的是一个没有 : 的时区偏移量,所以 +0100.

以下示例在使用 Python 3.6.7 的 Linux 上给出错误:

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

此示例代码产生此异常:

ValueError: 时间数据 '2019-01-19T15:13:00.000+01:00' 不匹配格式 '%Y-%m-%dT%H:%M:%S.%f%z'

如果我们从它工作的输入字符串中删除 : ,则不会抛出异常.

当我们在 Windows 和 Python 3.7.2 上运行该代码时,该代码也有效.

会不会是因为 Python 版本不同?我们如何解析或转换它而不会出错?

解决方案

是的,这是一个版本问题.您依赖于 Python 3.7 中引入的新功能

来自 datetime.strptime() 文档,第 6 个脚注:

<块引用>

在 3.7 版中更改:当 %z 指令提供给 strptime() 方法时,UTC 偏移量可以有一个冒号作为小时、分钟和秒之间的分隔符.例如,'+01:00:00' 将被解析为一小时的偏移量.

如果你不能在任何地方都升级到 Python 3.7,那么你可以通过一些预处理删除那些冒号:

导入重新datetimestring = re.sub(r'([-+]\d{2}):(\d{2})(?:(\d{2}))?$', r'\1\2\3', 日期时间字符串)

正则表达式从任何 HH:MMHH:MM:SS 偏移量中删除冒号(出现在字符串的结尾并以 -+) 开头:

演示:

<预><代码>>>>进口重新>>>从日期时间导入日期时间>>>datetimestring = "2019-01-19T15:13:00.000+01:00">>>更正后 = re.sub(r'([-+]\d{2}):(\d{2})(?:(\d{2}))?$', r'\1\2\3', 日期时间字符串)>>>更正'2019-01-19T15:13:00.000+0100'>>>datetime.strptime(更正后,'%Y-%m-%dT%H:%M:%S.%f%z')datetime.datetime(2019, 1, 19, 15, 13, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))

如果您要在任何地方升级到 Python 3.7,您可以完全放弃 strptime() 解析,只需使用专用的 datetime.fromisoformat() 方法;它可以直接解析您的输入.

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

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?

解决方案

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

这篇关于带有冒号的时区偏移的日期时间 strptime 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆