Python:strftime() UTC 偏移量在 Windows 中未按预期工作

问题描述 投票:0回答:5

每次使用时:

time.strftime("%z")

我得到:

Eastern Daylight Time

但是,我想要 +HHMM 或 -HHMM 形式的 UTC 偏移量。我什至尝试过:

time.strftime("%Z")

仍然产生:

Eastern Daylight Time

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

编辑:我运行的是 Windows 7

python windows offset utc strftime
5个回答
8
投票

在 2.x 中,如果您查看

time.strftime
的文档,他们甚至不会 提及
%z
。它根本无法保证存在,更不用说跨平台一致了。事实上,正如脚注 1 所暗示的那样,这取决于 C
strftime
函数。另一方面,在 3.x 中,他们确实提到了
%z
,并且解释它不按您期望的方式工作的脚注并不容易看到;这是一个未解决的错误

但是,在 2.6+(包括所有 3.x 版本)中,

datetime.strftime
is 保证支持
%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 之前的主干中,基本上也存在相同的差异。


7
投票

有关正确的解决方案,请参阅下面abarnert的回答


您可以使用

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'

正如 abarnert 在评论中提到的,

time.altzone
给出 DST 有效时的偏移量,而
time.timezone
给出 DST 未激活时的偏移量。要确定使用哪个,您可以按照 J.F. Sebastian 的建议在他对另一个问题的回答中进行操作。这样你就可以得到正确的偏移量,如下所示:

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'

4
投票

使用

time.timezone
获取时间偏移(以秒为单位)。

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

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

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

顺便说一句,这不是一个错误吗?根据

strftime
docs

我还认为this所以答案可能会帮助您从区域偏移字符串转换为 HH:MM 格式。但由于

"%z"
没有按预期工作,我觉得它没有实际意义。

注意:

time.timezone
不受夏令时影响。


0
投票

这个错误在当前可用的最新 Windows 版本 Win 10 Version 1703(Creators)中持续存在也就不足为奇了。然而,随着时间的推移,有一个名为 pendulum 的可爱的日期和时间库可以满足问题的要求。 Sébastien Eustace(该产品的主要作者?)向我展示了这一点。

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

pendulum 假定 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'

0
投票

我来这里寻找解决方案,因为我需要输出完整的日期和时间,包括另一个程序的时区,该程序需要 RFC3339 格式https://datatracker.ietf.org/doc/html/rfc3339(是的,挑剔吧?!):)

strftime 的输出并不符合这个特定的标准,所以最后我最终使用了:

from datetime import datetime, timezone
print(datetime.now(timezone.utc).astimezone().isoformat())

输出以下内容:

2024-03-06T10:43:00.348657+00:00

我知道这并不是问题的答案,但这似乎是一个明智的地方,以防有人和我一样陷入同一个兔子洞:)

© www.soinside.com 2019 - 2024. All rights reserved.