python 3中的时间对象str

时间:2018-06-28 13:34:57

标签: python python-3.x

给出一对str对象,它们代表一个ISO 8601时间和时区:

time_str = '09:30'

time_zone_str = 'America/New_York'

如何将这两个字符串解析为timenot datetime)对象?

注意:显然可以将time_str除以':'并使用时间构造函数,但是解析计数结果列表中的元素数量以了解分辨率会有些棘手(分钟,秒,微秒)的str。这是因为ISO 8601允许使用不同的表示形式:

 time_str_short = '09:30'

 time_str_long = '09:30:00'

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

3 个答案:

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

谢谢