给出一对str
对象,它们代表一个ISO 8601时间和时区:
time_str = '09:30'
time_zone_str = 'America/New_York'
如何将这两个字符串解析为time
(not datetime
)对象?
注意:显然可以将time_str
除以':'
并使用时间构造函数,但是解析计数结果列表中的元素数量以了解分辨率会有些棘手(分钟,秒,微秒)的str。这是因为ISO 8601允许使用不同的表示形式:
time_str_short = '09:30'
time_str_long = '09:30:00'
预先感谢您的考虑和答复。
答案 0 :(得分:1)
“我可以这样做吗?”的答案(带有时区)为是和否。首先,让我们将字符串转换为time
对象。正如一个评论者所提到的,您可以在Python 3.7中使用fromisoformat
方法来做到这一点:
from datetime import time
time.fromisoformat("09:30")
如果您未使用3.7,则可以通过创建datetime
然后转换为时间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:
不幸的是,在很多时区,pytz使用标准日期时间构造函数的tzinfo参数“不起作用”。 〜http://pytz.sourceforge.net/
因此,我们将不得不使用新创建的tzinfo对象的localize
方法。但是很遗憾,我们仍然无法在此时区成功定位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位置名称中得出。
答案 1 :(得分:1)
没有日期的时区是没有意义的,因此,不能,都不能使用两者来生成time
对象。标准库time
对象支持具有tzinfo
属性,而'timezone'对象并不是真正的时区,而只是时间偏移量。
时区不仅仅是UTC的偏移量。时区偏移量与日期有关,并且由于诸如夏令时冬季/夏季时间区分等详细信息部分是政治决策的结果,因此时区偏移量的更改日期也取决于年份。
为明确起见,America/New_York
是时区,而不是时间偏移。与UTC的确切偏移量取决于日期;夏天要少4小时,冬天要5小时!
因此对于诸如America/New_York
之类的时区,您还需要选择一个日期。如果您不关心日期,请选择一个固定日期,以便您的偏移量至少一致。如果要转换大量时间戳,请将时区偏移量存储为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())
之后,您可以根据需要将其添加到任何datetime
对象,以从UTC移至本地时间,或减去将其从本地移至UTC 。请注意,我说datetime
是因为time
对象也不支持timedelta
算法。毕竟,一个timedelta可以大于一天中剩余的秒数或自午夜以来的秒数,因此加法或减法可能会改变日期和时间:
# new time after shifting
(datetime.combine(datetime.now(), timeobject) + utc_offset).time()
为了完成起见,您不能将pytz时区传递给time
对象。它只是对时间没有任何影响。在这种情况下,时区对象返回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年引入的时区;直到20世纪才引入“现代” EST时区。这就是为什么在确定偏移量时通常在日期中传递时区对象的原因:
>>> tz.utcoffset(datetime(1883, 6, 28))
datetime.timedelta(-1, 68640)
>>> tz.utcoffset(datetime(1918, 6, 28))
datetime.timedelta(-1, 72000)
答案 2 :(得分:-1)
希望它对您有用,
import datetime
# Hello World program in Python
print "Hello World!\n"
time_str = '09:30'
time_zone_str = 'America/New_York'
s = "I am looking for a course in Paris!"
print(s)
print(datetime.datetime.strptime(time_str, '%H:%M').time())
print(datetime.time(3, 55))
谢谢