首页 > 解决方案 > python 3中的str到时间对象

问题描述

给定一对str表示ISO 8601时间和时区的对象:

time_str = '09:30'

time_zone_str = 'America/New_York'

如何将这 2 个字符串解析为timedatetime)对象?

注意:显然可以拆分time_strby':'并使用 time 构造函数,但是要计算结果列表中的元素数量以了解 str 的分辨率(分钟、秒、微秒),解析会有点棘手。这是因为ISO 8601允许不同的表示:

 time_str_short = '09:30'

 time_str_long = '09:30:00'

预先感谢您的考虑和回复。

标签: pythonpython-3.x

解决方案


“我可以这样做吗?”的答案 (带时区)是和否。首先让我们将字符串转换为time对象。正如一位评论者提到的,您可以在 python 3.7 中使用以下fromisoformat方法执行此操作:

from datetime import time
time.fromisoformat("09:30")

如果您不使用 3.7,则可以通过创建 adatetime然后转换为 time来做到这一点object

from datetime import datetime, time
as_time = datetime.datetime.strptime("09:00", "%H:%M").time()

现在处理时区。由于时区是一个名称,我们可以使用非常方便的pytz模块将其转换为 tzinfo 对象:

pytz.timezone('America/New_York')

此时,您可能很想将其作为 tzinfo 参数传递给时间构造函数,但不幸的是,这不适用于 pytz:

不幸的是,对于许多时区,使用标准日期时间构造函数的 tzinfo 参数对 pytz “不起作用”。~ http://pytz.sourceforge.net/

所以我们将不得不使用localize新创建的 tzinfo 对象的方法。但不幸的是,我们仍然无法time使用该时区成功本地化对象。这样做的原因是 pytz 需要知道日期才能确定该时区是否处于夏令时。由于我们没有提供日期,因此实现这一目标是非常不可能的,您会得到奇怪的结果,例如:

>>> pytz.timezone('America/New_York').localize(as_dt).isoformat()
'1900-01-01T09:00:00-04:56'

注意-04:56偏移量,这是乱码。有几种选择可以实现您最终想要的。

一种选择是假设时间是今天:

as_time = datetime.datetime.strptime("09:00", "%H:%M").time()
tz = pytz.timezone('America/New_York')
local_time = tz.localize(datetime.datetime.now().replace(hour=as_time.hour, minute=as_time.minute))

另一种选择是使用天真的时区偏移量而不是时区名称:

from datetime import timezone, timedelta  
naive_tz = timezone(timedelta(hours=5))
datetime.time(9, 30).replace(tz_info=naive_tz)

但我不推荐这种方法,因为它非常脆弱,并且需要一些中间步骤来从 TZ 位置名称派生,这些步骤非常重要。


推荐阅读