Python:strftime()UTC Offset在Windows中不能按预期工作

时间:2014-08-07 16:20:36

标签: python windows offset utc strftime

每次我使用:

time.strftime("%z")

我明白了:

Eastern Daylight Time

但是,我希望UTC偏移量为+ HHMM或-HHMM。我甚至尝试过:

time.strftime("%Z")

仍然产生:

Eastern Daylight Time

我已经阅读了几篇与strftime()相关的帖子,而且%z似乎总是以正确的+ HHMM或-HHMM格式返回UTC偏移量。如何让strftime()以+ HHMM或-HHMM格式输出python 3.3?

编辑:我正在运行Windows 7

4 个答案:

答案 0 :(得分:7)

在2.x中,如果查看time.strftime的文档,他们甚至不会提及 %z。它根本不能保证存在,更不用说跨平台保持一致。实际上,正如footnote 1所暗示的那样,它由C strftime函数决定。另一方面,在3.x中,他们确实提到了%z,并且脚注解释说它不能按照您期望的方式工作,这不容易看到;那是an open bug

但是,在2.6+(包括所有3.x版本)中,datetime.strftime 保证支持%z“格式为+ HHMM或-HHMM的UTC偏移(如果对象是天真的,则为空字符串)。“因此,这使得一个非常简单的解决方法:使用datetime而不是time。究竟如何更改内容取决于您尝试做什么 - 使用Python-dateutil tz然后datetime.now(tz.tzlocal()).strftime('%z')是获取格式化为GMT偏移的本地时区的方法,但是如果你试图格式化一个完整的时间,细节会有所不同。

如果查看源代码,time.strftime基本上只检查格式字符串是否为有效的平台说明符并调用本机strftime函数,而datetime.strftime有一堆对不同说明者的特殊处理,包括%z;特别是,在将内容传递给%z之前,它会将utcoffset替换为strftime的格式化版本。自2.7以来,代码已经改变了几次,甚至已经彻底重组了一次,但即使在3.5之前的主干中也存在相同的差异。

答案 1 :(得分:4)

要获得正确的解决方案,请参阅abarnert’s answer below


您可以使用time.altzone以秒为单位返回负偏移量。例如,我现在正在使用CEST(UTC + 2),所以我明白了:

>>> time.altzone
-7200

并按照您想要的格式:

>>> '{}{:0>2}{:0>2}'.format('-' if time.altzone > 0 else '+', abs(time.altzone) // 3600, abs(time.altzone // 60) % 60)
'+0200'

正如评论中提到的那样,time.altzone在DST处于活动状态时给出偏移量,而time.timezone在DST未激活时给出偏移量。要弄清楚要使用哪个,你可以做J.F.Sebastian所建议的in his answer to a different question。所以你可以得到正确的偏移量:

time.altzone if time.daylight and time.localtime().tm_isdst > 0 else time.timezone

正如他所建议的,你可以使用Python 3中的以下内容来使用datetime.timezone获得所需的格式:

>>> datetime.now(timezone.utc).astimezone().strftime('%z')
'+0200'

答案 2 :(得分:4)

使用time.timezone以秒为单位获取时间偏移量。

使用以下方式对其进行格式化:

("-" if time.timezone > 0 else "+") + time.strftime("%H:%M", time.gmtime(abs(time.timezone)))

将其转换为+/- HH:MM格式。

BTW这不应该是一个错误吗?根据{{​​1}} docs

另外我认为this所以答案可能会帮助您将区域偏移字符串转换为HH:MM格式。但由于strftime没有达到预期的效果,我觉得它没有实际意义。

注意:time.timezone不受夏令时的影响。

答案 3 :(得分:0)

毫无疑问,这个bug仍然存在,目前最新的Windows版本是什么,Win 10版本1703(创作者)。然而,时间在前进,有一个可爱的日期和时间库,名为pendulum,可以解决问题所要求的问题。 SébastienEustace(该产品的主要作者?)向我展示了这一点。

>>> pendulum.now().strftime('%z')
'-0400'
除非另有说明,否则

钟摆将采用UTC / GMT,并将时区与日期时间对象保持一致。还有许多其他可能性,其中包括:

>>> pendulum.now(tz='Europe/Paris').strftime('%z')
'+0200'
>>> pendulum.create(year=2016, month=11, day=5, hour=16, minute=23, tz='America/Winnipeg').strftime('%z')
'-0500'
>>> pendulum.now(tz='America/Winnipeg').strftime('%z')
'-0500'