【问题标题】:How to render timestamp according to the timezone in PythonPython中如何根据时区渲染时间戳
【发布时间】:2020-07-26 10:04:20
【问题描述】:

我有两个日期时间对象,它们代表不同时区的相同日期时间值。我想将它们转换为 POSIX 时间戳。然而,无论时区如何,看似调用 datetime.timestamp() 都会返回一个值。

from datetime import datetime
import pytz

dt = datetime(2020, 7, 26, 6, 0) 
utc_dt = pytz.utc.localize(dt) # datetime.datetime(2020, 7, 26, 6, 0, tzinfo=<UTC>)
bp = pytz.timezone("Europe/Budapest")
bp_dt = utc_dt.astimezone(bp)  # datetime.datetime(2020, 7, 26, 8, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CEST+2:00:00 DST>)
utc_dt.timestamp() # 1595743200.0
bp_dt.timestamp()  # 1595743200.0

documentation of datetime.timestamp() 表示如下:

对于感知日期时间实例,返回值计算为:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

运行utc_dt - bp_dt 返回datetime.timedelta(0)。所以它似乎是用 datetime 对象的 UTC 值计算的。

我在网络堆栈中使用 Python。我希望后端处理时区处理,并让客户端在 API 响应中接收用户时区中预先计算的日期时间值。

获取时区感知时间戳的 Pythonic 方法是什么?

【问题讨论】:

  • POSIX timestamps 应始终引用 UTC 以明确无误 - 否则,您必须将时区信息绑定到数字 - 本质上,您有 datetime 用于此目的的对象。所以简而言之,我会说你没有
  • @MrFuppes 我理解,但我不明白为什么我仍然无法获得 naive 时间戳对象。我希望后端处理时区,客户端应该只接收预先计算的日期时间值。
  • 这很好,但是客户端将如何处理时间戳?如果你例如转换回 Python (datetime.fromtimestamp()) 中的日期时间对象,它将假定时间戳是指 UTC,并在客户端的时区设置(客户端的本地时间)中为您提供一个类似于 UTC 的天真日期时间对象。
  • @MrFuppes 客户端读取时间戳并根据用户的语言显示。我想将客户端收到的 UTC 6:00 存储为 8:00 并将其显示为上午 8 点。
  • 好吧,我仍然希望传递 POSIX 时间戳,引用 UTC 并在客户端进行本地化 ;-) Unix 时间非常普遍,因此在最常见的情况下应该有一种方便的方法来执行此操作语言。

标签: python datetime timezone


【解决方案1】:

简而言之,我不建议这样做,因为您可能会造成一团糟,请参阅我的评论。


技术上,您可以通过简单地将datetime 对象的tzinfo 属性替换为UTC 来实现。请注意,我在这里使用dateutil.tz,所以我可以直接设置初始时区(没有 localize())。

from datetime import datetime, timezone
from dateutil import tz

dt = datetime(2020, 7, 26, 6, 0, tzinfo=tz.gettz("Europe/Budapest"))
# dt.utcoffset()
# >>> datetime.timedelta(seconds=7200)

# POSIX timestamp that references to 1970-01-01 UTC:
ts_posix = dt.timestamp()

# timestamp that includes the UTC offset:
ts = dt.replace(tzinfo=timezone.utc).timestamp()

# ts-ts_posix
# >>> 7200.0

【讨论】:

  • 感谢您指出dateutil.tz!我不知道它也可以用来处理时区。我之前试过datetime.replace(),你也提到过,但我得到了一个奇怪的结果和pytz。我刚刚阅读了这篇关于比较两个包的漂亮文章——blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html——它还总结了使用dateutil.tz
  • @viam0Zah:jep,读起来很有见地!顺便说一句,说到 Paul Ganssle,在 Pyrhon 3.9 中,时区处理将成为标准库的一部分,请参阅zoneinfo
  • 我在Django的timezone.make_naive()实现中找到了类似的解决方案:dt.astimezone(timezone).replace(tzinfo=None)github.com/django/django/blob/master/django/utils/…
  • @viam0Zah: 对那个 django 函数不太熟悉 - 它会给你一个 datetime 对象吗?如果是这样,如果您随后调用它的 timestamp,Python 将假定它是本地时间(您运行它的机器的时区设置)并在返回时间戳之前转换为 UTC。这就是为什么我用 UTC 替换 tzinfo,以规避这种转换。
猜你喜欢
  • 2014-03-13
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2018-04-09
  • 1970-01-01
  • 2018-03-04
  • 2015-11-14
相关资源
最近更新 更多