str在python 3中的时间对象

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

time_str = '09:30'

time_zone_str = 'America/New_York'

如何将这2个字符串解析为time(not datetime)对象?

注意:很明显可以将time_str拆分为’:’并使用时间构造函数,但是解析在结果列表中计算元素数量以了解分辨率(分钟,秒,微秒)时会有点棘手.海峡.这是因为ISO 8601允许不同的表示:

 time_str_short = '09:30'

 time_str_long = '09:30:00'

提前感谢您的考虑和回应.

最佳答案 没有日期的时区是没有意义的,所以不,你不能同时使用它们来生成时间对象.虽然标准库时间对象确实支持具有tzinfo属性,但“时区”对象实际上不是时区,而只是时间偏移.

时区不仅仅是与UTC的偏移.时区偏移取决于日期,因为夏令时冬季/夏季时间区分等细节部分是政治决策的结果,时区偏移变化的日期也取决于年份.

明确地说,America / New_York是一个时区,而不是时间偏移.与UTC的确切偏差取决于日期;夏天是零下4小时,冬天是5小时!

所以对于像America / New_York这样的时区,你也需要选择一个日期.如果您不关心日期,请选择固定日期,以使您的偏移量至少保持一致.如果要转换大量时间戳,请将时区偏移量存储为timedelta()一次,然后使用该timedelta将time()对象移位到右侧偏移量.

要解析一个时间字符串,假装使用datetime.strptime()方法附加日期,然后提取时间对象:

from datetime import datetime

try:
    timeobject = datetime.strptime(time_str, '%H:%M').time()
except ValueError:
    # input includes seconds, perhaps
    timeobject = datetime.strptime(time_str, '%H:%M:%S').time()

要更新给定时区的时间,请首先获取支持时区字符串的时区数据库; pytz library定期更新.

from pytz import timezone

timezone = pytz.timezone(time_zone_str)

你如何使用它取决于你想要做什么.如果输入时间不是UTC,您可以使用datetime.combine()method将时区附加到datetime()对象,之后可以将其移动到UTC时区:

dt_in_timezone = datetime.combine(datetime.now(), timeobject, timezone)
utc_timeobject = dt_in_timezone.astimezone(pytz.UTC).time()

这假设’今天’足以确定正确的偏移量.

如果您的时间是UTC时间戳,请将其与UTC时区结合使用,然后使用pytz时区;实际上反过来:

dt_in_utc = datetime.combine(datetime.now(), timeobject, pytz.UTC)
timeobject_in_timezone = dt_in_timezone.astimezone(timezone).time()

要仅存储批量应用程序的偏移量,请将参考日期传递给timezone.utcoffset() method

utc_offset = timezone.utcoffset(datetime.now())

之后,您可以根据需要将其添加到任何日期时间对象,以便从UTC移动到本地时间,或者将其减去从本地到UTC.注意我说的是datetime,因为时间对象也不支持timedelta算术; timedelta可以大于当天剩余的秒数或者自午夜以来的秒数,因此增加或减少可能会改变天数和时间:

# new time after shifting
(datetime.combine(datetime.now(), timeobject) + utc_offset).time()

为了完成,您不能将pytz时区传递给时间对象;它只是对时间没有任何影响.在这种情况下,时区对象为UTC偏移返回None,因为如果没有日期,它无法给出任何有意义的答案:

>>> from datetime import time
>>> from pytz import timezone
>>> tz = timezone('America/New_York')
>>> time_with_zone = time(12, 34, tzinfo=tz)
>>> time_with_zone
datetime.time(12, 34, tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>)
>>> time_with_zone.utcoffset()
>>> time_with_zone.utcoffset() is None
True
>>> tz.utcoffset(None) is None    # what time_with_zone.utcoffset() does under the hood
None

因此,对于所有意图而言,time_with_zone只是另一个天真的时间对象,因为附加的tzinfo对象实际上没有任何效果.

此外,因为没有确定正确时区信息的日期,所以pytz选择了最早的已知“纽约”时区,而这并不是最近的时区.仔细看看那个tzinfo表示:

tzinfo=<DstTzInfo 'America/New_York' LMT-1 day, 19:04:00 STD>
                                     ^^^^^^^^^^^^^^^^^^^^^^^

这是1883年由铁路公司引入的时区; “现代”的EST时区直到20世纪才被引入.这就是为什么时区对象通常在确定偏移量时的日期中传递的原因:

>>> tz.utcoffset(datetime(1883, 6, 28))
datetime.timedelta(-1, 68640)
>>> tz.utcoffset(datetime(1918, 6, 28))
datetime.timedelta(-1, 72000)
点赞