我从一个较大的项目中提取了以下简单的代码。我试图通过提取日、月、年来模拟期货日期,我使用的是std::chrono库。我使用std::chrono库,过了一定的天数(在我的电脑上大约是8835天),日期出错了。
你能重现这种行为吗?
// COMPILE OK && RUN KO (wandbox)
// g++ prog.cc -O2 -march=native -std=c++11
// COMPILE OK && RUN OK (wandbox)
// clang++ prog.cc -Wall -Wextra -std=c++11
#include <iostream>
#include <chrono>
using namespace std;
int main(int ac, char* av[])
{
(void) ac; (void) av;
auto faketime = chrono::system_clock::now();
for( int i=0; i<100000; ++i) {
// doDaily();
faketime += chrono::hours(24);
time_t ftime = chrono::system_clock::to_time_t(faketime);
if( i% 1000 == 0)
cout << "faketime (" << ftime << ") is : " << ctime(&ftime) << endl;
}
auto currtime = chrono::system_clock::now();
time_t cutime = chrono::system_clock::to_time_t(currtime);
cout << "currtime is : " << ctime(&cutime);
return 0;
}
结果(第三行出错) 。
[...]
faketime (9105738161) is : Tue Jul 20 20:42:41 2258
faketime (9192138161) is : Mon Apr 15 20:42:41 2261
faketime (-9168205912) is : Wed Jun 21 21:27:07 1679
faketime (-9081805912) is : Tue Mar 17 21:27:07 1682
faketime (-8995405912) is : Mon Dec 11 21:27:07 1684
currtime is : Thu May 7 12:48:56 2020
编辑了 。
你正在经历一个溢出 system_clock::time_point
.
准确度 system_clock::time_point
因平台而异。
但是 代表性 在三个平台上都是一样的:签名64位积分。 而这都是符合要求的。
64个签名位的纳秒得到的范围大约是+-292年。 对于 system_clock
这个范围是以1970-01-01为中心。 所以2262年的溢出是正常的。
如果你需要更大的范围,你可以降低精度。 比如说
auto faketime = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now());
我们可以通过编程来检查一个极限 time_point
随着 time_point
静态成员函数 min()
和 max()
.
微秒的范围约为+-292。千人 年。 我不知道什么范围在 ctime
是的,但如果它能格式化过去未来那么远的日期,我会感到惊讶。