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

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

本文关键字:time point 实例 出错 chrono 比较 两个 std      更新时间:2023-10-16

我在变量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-4243023785

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

显然,在您的平台上实现ctime无法处理过去这么远的日期,这有点令人惊讶,因为 1835 年已经过去不远了。

exp的值是-4243023785乘以 100 万或 10 亿(取决于平台上system_clock精度(,并使用有符号的 64 位整数存储(没有溢出(。 因此time > exp == 1是正确的(time1590775919s转换为system_clock的精度(。

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

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

更新

87990716383正在转换为time_point

,使用from_time_t()

啊,这与在您的平台上system_clock精度nanoseconds的知识相结合,告诉我您在exp的构建中遇到了溢出.

这不是您拥有的代码:

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-01-01 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