Python datetime utcnow 没有设置时区?

Python datetime utcnow does not set timezone?

发现这个问题与时间戳转换一起使用,其中 .timestamp() 似乎补偿了时间偏移,即使我使用 utcnow() 方法创建了 datetime 对象。那么 utcnow() 方法在稍后转换为时间戳时实际上失败的原因是什么?

def test_timestamp_issues():
    now = datetime.now()
    utc_now = datetime.utcnow()
    utc_now_with_tz = datetime.now(timezone.utc)
    print(f"Now: {now} -- As Timestamp: {now.timestamp()}")
    print(f"Utc Now: {utc_now} -- As TimeStamp: {utc_now.timestamp()} "
          f"with builtin: {datetime.timestamp(utc_now)}, with setting timezone hard: "
          f"{utc_now.replace(tzinfo=timezone.utc).timestamp()}")
    print(f"Utc Now: {utc_now_with_tz} -- As TimeStamp: {utc_now_with_tz.timestamp()} "
          f"with builtin: {datetime.timestamp(utc_now_with_tz)}, with setting timezone hard: "
          f"{utc_now_with_tz.replace(tzinfo=timezone.utc).timestamp()}")

输出:

Now: 2022-04-25 09:12:16.881608 -- As Timestamp: 1650870736.881608
Utc Now: 2022-04-25 07:12:16.881613 -- As TimeStamp: 1650863536.881613 with builtin: 1650863536.881613, with setting timezone hard: 1650870736.881613
Utc Now: 2022-04-25 07:12:16.881753+00:00 -- As TimeStamp: 1650870736.881753 with builtin: 1650870736.881753, with setting timezone hard: 1650870736.881753

这里的预期时间戳应该是 1650870736.881608 但由于某种原因转换 utcnow() 再次向后提供 2 小时。

因此,出于某种原因,我在获取 utcnow() 创建的日期时间对象的时间戳时又得到了 2 小时的提款。我目前是 运行 macbook m1 pro,使用挪威时区(+1、+2 atm 日光)和 python 3.9.12

这可能是 arm 架构搞砸了,还是不建议使用 utcnow() 然后转换为时间戳?

您问题的答案是管理时区 (TZ)。当您使用 now()utcnow() 创建一个 datetime 实例时,它不会存储有关 TZ 的信息。并且,根据 python docs for utcnow() (作者加粗):

Return the current UTC date and time, with tzinfo None.

This is like now(), but returns the current UTC date and time, as a naive datetime object. An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc). See also now().

Warning: Because naive datetime objects are treated by many datetime methods as local times, it is preferred to use aware datetimes to represent times in UTC. As such, the recommended way to create an object representing the current time in UTC is by calling datetime.now(timezone.utc).

这意味着,虽然您收到了 utcnow() 的 UTC TZ 时间,但由于没有存储 TZ 信息(原始 datetime 对象),python 将其视为本地时间时间。并且,将其转换为时间戳时,会再次add/subtract时差。在 python docs for timestamp() 方法中可以找到这种奇怪行为的证据:

Naive datetime instances are assumed to represent local time

其实是题主说的那个原因,不是ARM架构