为什么在使用 datetime.max 时会出现 ValueError?

Why do I get a ValueError when using datetime.max?

为什么我在这个例子中得到了 ValueError

>>> import datetime
>>> datetime.datetime.max.timestamp()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year 10000 is out of range

我正在使用 Python 3.8.3.

我使用 Python 3.6 获得 OSError: [Errno 22] Invalid argument。文档是这样说的:

备注

无法直接从表示 UTC 时间的原始日期时间实例获取 POSIX 时间戳。如果您的应用程序使用此约定并且您的系统时区未设置为 UTC,则可以通过提供 tzinfo=timezone.utc:

来获取 POSIX 时间戳
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

或者直接计算时间戳:

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

所以当我尝试时:

>>> import datetime
>>> datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()
253402300800.0

你的语法不正确.. datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0) 需要年、月和日参数。 tzinfo 可能是 None,或者是 tzinfo 子类的一个实例。其余参数必须是以下范围内的整数:

MINYEAR <= year <= MAXYEAR,

1 <= 月 <= 12,

1 <= 天 <= 给定月份和年份中的天数,

0 <= 小时 < 24,

0 <= 分钟 < 60,

0 <= 秒 < 60,

0 <= 微秒 < 1000000,

折叠 [0, 1]。

timestamp() 方法实际上将您的日期时间转换为 local 时区。如果您的时区是 UTC+x(不是 UTC-x);即您的时区早于 UTC 时间;然后它将在您的日期时间对象 (datetime.datetime.max) 中添加更多时间,这将跨越 9999 年之后的时间。这就是为什么您的代码会出现该错误。

下面是一个验证它的例子:

val1 = datetime.datetime.now()  # datetime.datetime(2020, 6, 15, 15, 54, 15, 214349)

val1 是我所在时区的确切时间,但没有与之关联的时区(因此它将采用 local 时区,因为 datetime.datetime.max拿)。您可以使用 val1.tzinfo 检查日期时间对象中的时区。如果它 returns 空白,这意味着代码假定时间在 local 时区。

我在同一时间又创建了一个对象,但使用的是 UTC 时区:

val2 = datetime.datetime.fromisoformat("2020-06-15T15:54:15.214349+00:00")

我打印值:

print(val1.timestamp()) # 1592216655.214349
print(val2.timestamp()) # 1592236455.214349

如果你计算这两个值之间的差异,它将给出 19,800 秒(即 5.5 小时),这正是我的时区(IST 或者你可以说 UTC+5:30)与 UTC 的差异。