比较两个 std::chrono::time_point 个实例时出错

Error in comparing two std::chrono::time_point instances

我在变量 exptime 中有两个 std::chrono::time_point 实例。 exp 是未来的时间,time 是现在的时间。但是当我在这个片段中比较它们时:

std::time_t t_exp = std::chrono::system_clock::to_time_t(exp);
std::time_t t_time = std::chrono::system_clock::to_time_t(time);
std::cout << std::ctime(&t_exp) << std::ctime(&t_time) << (time > exp) << std::endl;

我得到输出:

Sat Apr 26 01:39:43 4758
Fri May 29 18:11:59 2020
1

这是错误的,因为 exp 是 4758 年,而 time 是 2020 年。

我哪里错了?

t_exp is -4243023785

这个time_t的值对应于1835-07-1822:16:55(假设Unix纪元和秒精度,这两者都不是标准指定的,但是很常见)。

显然 ctime 在您的平台上的实现无法处理过去这么久的日期,这有点令人惊讶,因为 1835 并不是过去的很长时间。

exp 的值是 -4243023785 百万或十亿倍(取决于您平台上 system_clock 的精度),并以带符号的 64 位整数(没有溢出)。因此 time > exp == 1 是正确的(time1590775919s 转换为 system_clock 的精度)。

4 月 26 日星期六 01:39:43 4758 对应于 time_t 87990716383。

我认为您在上述代码中使用 chrono 库没有任何问题。

更新

The value 87990716383 is being converted to a time_point using from_time_t()

啊,结合你的平台上 system_clock 的精度是 nanoseconds 的知识告诉我你在构建 exp.[=39 时遇到了溢出=]

这不是您拥有的代码:

std::time_t t_exp = std::chrono::system_clock::to_time_t(exp);
std::time_t t_time = std::chrono::system_clock::to_time_t(time);
std::cout << std::ctime(&t_exp) << std::ctime(&t_time) << (time > exp) << std::endl;

您的代码类似于:

// ...
std::time_t t_exp = 87990716383;
auto exp = std::chrono::system_clock::from_time_t(t_exp);
std::cout << std::ctime(&t_exp) << std::ctime(&t_time) << (time > exp) << std::endl;

在您的平台上,system_clock 以带符号的 64 位整数存储自 1970 年 1 月 00:00:00 UTC 以来的 nanoseconds。您平台上的最大可存储日期 (system_clock::time_point::max()) 是:

2262-04-11 23:47:16.854775807

除此之外,nanoseconds 的底层存储溢出。

87990716383(秒)在from_time_t中转换时,乘以十亿溢出。溢出的值为 -4243003985547758080,对应于日期 1835-07-19 03:46:54.452241920.

您可以使用较粗的精度来获得更大的范围,例如:

std::time_t t_exp = 87990716383;
time_point<system_clock, microseconds> exp{seconds{t_exp}};
// exp == 4758-04-26 01:39:43.000000