比较两个 std::chrono::time_point 个实例时出错
Error in comparing two std::chrono::time_point instances
我在变量 exp
和 time
中有两个 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
是正确的(time
是 1590775919s
转换为 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
我在变量 exp
和 time
中有两个 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
是正确的(time
是 1590775919s
转换为 system_clock
的精度)。
4 月 26 日星期六 01:39:43 4758 对应于 time_t
87990716383。
我认为您在上述代码中使用 chrono
库没有任何问题。
更新
The value 87990716383 is being converted to a
time_point
usingfrom_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