为什么 datetime.datetime.now().timestamp() 和 datetime.datetime.utcnow().timestamp() 有区别?

Why the difference between datetime.datetime.now().timestamp() and datetime.datetime.utcnow().timestamp()?

据我所知,自 Unix 纪元 (1970-01-01 00:00:00 UTC) 以来的秒数应该在全球各地都相同,因为它固定为UTC.

现在,如果您所在的时区有几个小时 +/- UTC,为什么这样做会得到不同的时间戳(在我的情况下为 +2 小时)

>>> datetime.datetime.utcnow().timestamp()
1523622844.637763
>>> datetime.datetime.now().timestamp()
1523630048.558158

如果考虑到 运行 第二行代码所花费的时间,您会得出两个时间戳之间相差 7200 秒(2 小时)的结论。这些时间戳不应该是不知道时区的吗?

您计算机的 BIOS 可能设置为本地时间而不是 UTC 时间。一般来说,对于系统 运行 unix 之类的操作系统,UTC 时间是常态。对于系统 运行 Windows 当地时间是常态。 .now() 应该与您在计算机时钟上看到的显示时间相同,而 .utcnow() 不知道您在 OS 中设置的时区偏移量,它会显示 UTC 日期和时间。

来自docs

  • datetime.now(): returns 当前 本地 日期和时间。
  • datetime.utcnow(): returns 当前 UTC 日期和时间 [...]。这就像 now(),但是 returns 当前的 UTC 日期和时间,作为天真的 datetime

举个例子:

偏移量

In [1]: datetime.datetime.now()
Out[1]: datetime.datetime(2018, 4, 13, 17, 8, 4, 457551)

In [2]: datetime.datetime.utcnow()
Out[2]: datetime.datetime(2018, 4, 13, 15, 8, 5, 385598)

无偏移

In [3]: datetime.datetime.now(tz=pytz.utc)
Out[3]: datetime.datetime(2018, 4, 13, 15, 8, 59, 590874, tzinfo=<UTC>)

In [4]: datetime.datetime.utcnow()
Out[4]: datetime.datetime(2018, 4, 13, 15, 9, 1, 494370)

datetime.now()utcnow() 是 TZ 未知的(即默认的 tzinfoNone)。

来自文档 (https://docs.python.org/3.6/library/datetime.html#datetime.datetime.timestamp):

Naive datetime instances are assumed to represent local time

而且,至关重要的是:

Note: There is no method to obtain the POSIX timestamp directly from a naive datetime instance representing UTC time. If your application uses this convention and your system timezone is not set to UTC, you can obtain the POSIX timestamp by supplying tzinfo=timezone.utc: timestamp = dt.replace(tzinfo=timezone.utc).timestamp() or by calculating the timestamp directly:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

换句话说,在您的示例中,timestamp 的正确值是第二个(使用 now())。