给定一对表示
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)