我收集了一些要转换为增强(1.65.1)日期的unix时间戳,但是当它们将来距离太远时,转换似乎会中断。2040年及以后的一切似乎都在以某种方式回溯到1900年以后。
给定以下代码...
{
std::time_t t = 1558220400;
boost::gregorian::date date = boost::posix_time::from_time_t(t).date();
std::cout << "Date: " << date << std::endl;
}
{
std::time_t t = 2145500000;
boost::gregorian::date date = boost::posix_time::from_time_t(t).date();
std::cout << "Date: " << date << std::endl;
}
{
std::time_t t = 2500000000;
boost::gregorian::date date = boost::posix_time::from_time_t(t).date();
std::cout << "Date: " << date << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
...我得到以下输出...
Date: 2019-May-18
Date: 2037-Dec-27
Date: 1913-Feb-13
Run Code Online (Sandbox Code Playgroud)
...但是我期待以下输出...
Expected output:
Date: 2019-May-18
Date: 2037-Dec-27
Date: 2049-Mar-22
Run Code Online (Sandbox Code Playgroud)
我在这里做错什么了吗?
您似乎遇到了 2038 年问题。
32 位有符号整数可表示的最大数字是 2'147'483'647。自 1970 年 1 月 1 日 00:00:00 UTC(UNIX 纪元)以来的 2'147'483'647 秒是 2038 年 1 月 19 日 03:14:07 UTC。此后的任何 UNIX 时间都无法使用 32 位带符号表示整数。
要么std::time_t在系统上是32位,要么在boost库内部转换成32位。从源码中可以看到boost 将输入转换为longusing static_cast(并且在1.70版本中仍然如此)。long例如在 Windows 上是 32 位,甚至在 64 位架构上也是如此。在许多其他系统(例如 64 位 Linux)上它是 64 位的。