现在 utcnow() 已弃用,您如何在 Python 中获取 UTC 时间偏移量?[复制]

How do you get the UTC time offset in Python now that utcnow() is deprecated? [duplicate]

提问人:ullix 提问时间:11/3/2023 最后编辑:ullix 更新时间:11/21/2023 访问量:165

问:

这个问题在这里已经有答案了:
18天前关闭。

这篇文章是 18 天前编辑并提交审核的。

我需要当前位置和 UTC 之间的时差(以秒为单位)。它与(例如柏林时区,UTC+1h)配合得很好:

import datetime
datetime.datetime.utcnow().timestamp(): 1699017779.016835
datetime.datetime.now().timestamp():    1699021379.017343 # 3600 sec larger, correct!

但是现在被标记为已弃用,我需要并使用时区对象加载它:utcnow()now()

datetime.datetime.now(datetime.timezone.utc): 2023-11-03 14:22:59.018573+00:00
datetime.datetime.now():                      2023-11-03 15:22:59.018941    # 1 h later, correct!

也给出了正确的结果。但是,由于我想要时间戳,我像以前一样,但得到错误的结果:

datetime.datetime.now(datetime.timezone.utc).timestamp()) 1699021379.019286 # UTC  : is actually local timestamp
datetime.datetime.now().timestamp())                      1699021379.019619 # Local: why no difference ???

Local 是正确的,但 UTC 现在给出的时间戳与 Local 完全相同,这是错误的!我遗漏了什么还是这只是一个错误?

编辑:

在查看了所有评论后,我不同意一些评论者的观点 - 我认为 utcnow() 没有任何问题。它确实给出了调用时刻的 UTC 时间戳。当然,当您询问UTC时间时,不涉及时区!似乎错误的是将时间戳用于其他地方,其中包括与UTC的时差,并将其视为UTC / UNIX时间戳?

但也许我应该更清楚地表达我的需求:我想要我的时区和 UTC 之间的时差(以秒为单位)。有没有更简单的方法可以在 Python 中实现这一点?

没有一个答案和评论能提供这个问题的答案。

编辑2

我找到了 2 种可能的解决方法:

import datetime as dt
# workaround #1
ts = time.time()
utc   = dt.datetime.fromtimestamp(ts, tz=datetime.timezone.utc)                     # 2023-11-06 11:49:30.154083+00:00
local = dt.datetime.fromtimestamp(ts, tz=None)                                      # 2023-11-06 12:49:30.154083
ts_utc   = dt.datetime.strptime(str(utc)  [0:19], "%Y-%m-%d %H:%M:%S").timestamp()  # 1699267770.0
ts_local = dt.datetime.strptime(str(local)[0:19], "%Y-%m-%d %H:%M:%S").timestamp()  # 1699271370.0  # more by 3600 sec
TimeZoneOffset = ts_local - ts_utc                                                  # +3600 (sec)

# workaround #2
TimeZoneOffset = dt.datetime.now().astimezone().utcoffset().total_seconds()         # +3600 (sec)
python 日期时间 unix-timestamp

评论

1赞 JonSG 11/3/2023
这行得通吗??datetime.datetime.utcfromtimestamp(now.timestamp()).timestamp()
1赞 FObersteiner 11/3/2023
datetime.datetime.utcnow().timestamp(): 1699017779.016835- 这就是该方法首先被弃用的原因。它具有误导性和容易出错,因为从 utcnow() 返回的日期时间的结果不是 Unix 时间。
4赞 FObersteiner 11/3/2023
至于你认为的“错误”,Unix时间指的是UTC,所以两个时间戳实际上必须相同。
2赞 Malcolm 11/3/2023
时间戳不是本地的。它们是全球性的。这是它们有用性的一部分。
3赞 Abdul Aziz Barkat 11/3/2023
这回答了你的问题吗?UNIX 时间戳会因时区而异吗?另外:为什么 datetime.datetime.utcnow() 不包含时区信息?

答:

3赞 Malcolm 11/3/2023 #1

unix 时间戳是自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数。它是一个全局值,而不是局部值,这就是它的用处。

问题实际上出在.要么你的原始示例代码答案颠倒了,要么你位于格林威治以东,你的时区早于 UTC,你实际上应该期待一个更小的时间戳。对我来说,我比 UTC 时间晚 4 小时(即格里维奇以西)。utcnowutcnow

>>> datetime.datetime.utcnow().timestamp()
1699038850.622385
>>> datetime.datetime.now().timestamp()
1699024453.862131
>>> 

所以,对我来说,utcnow时间戳更大。问题在于生成一个没有嵌入时区信息的对象。因此,当您调用 timestamp 时,您将获得本地时间是现在的 UTC 时间的时间戳。datetime.datetime.utcnow()datetime.datetime

我希望这是弃用的部分原因。utcnow

评论

0赞 ullix 11/4/2023
正如我所说,我在柏林时区,UTC+1h,即格林威治以东,我的 now() 和 utcnow() 结果表明了这一点。utcnow() 可能没有嵌入时区,但根据定义,它不需要时区,因为它独立于时区。对我来说,utcnow() 是正确的。在我看来,其他时间戳包含时区差异,同时被指定为 UNIX 时间,这似乎是有问题的。当我们假设 UNIX 时间 == UTC 时间时,它们不是。utcnow() 是正确的,不应该被弃用!
0赞 FObersteiner 11/4/2023
@ullix支持 Malcolm 的回答 - “utcnow() 可能没有嵌入时区,但根据定义是不需要时区” - >这不是 datetime 作为数据结构在概念上的工作方式。关键是,朴素的 datetime(未附加 tzinfo)在 Python 中被解释为本地时间,无论它是来自 datetime.now 还是 datetime.utcnow。但是,“utcnow”表明它被解释为 UTC,但事实并非如此。恕我直言,实际问题出在 Python datetime 的设计中说天真 == 本地。结合 Unix 时间方法,这是一剂强心针。