std::gmtime
时, std::time_t
失败了。请参阅以下测试:
std::cout << "sizeof(std::time_t): " << sizeof(std::time_t) << '\n'
<< "sizeof(long long): " << sizeof(long long) << '\n'
<< "sizeof(unsigned int): " << sizeof(unsigned int) << "\n\n";
auto testgmtime = [](std::time_t time)
{
std::tm* ptm = std::gmtime(&time);
std::cout << (ptm ? "succeeded\n" : "failed\n");
};
testgmtime(std::numeric_limits<std::time_t>::max());
testgmtime(std::numeric_limits<long long>::max());
testgmtime(std::numeric_limits<long long>::max()-1);
testgmtime(static_cast<std::time_t>(std::numeric_limits<unsigned int>::max())*2);
testgmtime(std::numeric_limits<int>::max());
输出:
sizeof(std::time_t): 8
sizeof(long long): 8
sizeof(unsigned int): 4
failed
failed
failed
succeeded
succeeded
我正在使用VS2012。是否有标准限制我没有看到或者这个VS是不是很糟糕?我可以使用哪种替代工作?
答案 0 :(得分:2)
VS2012并不蹩脚。做数学。
如果time_t
是64位整数,那么如果它是无符号整数或2 63 64 -1 > -1如果它是有符号整数。
粗略地,2 63 秒对应于2 63 /(60 * 60 * 24 * 365)≈2.9* 10 11 年。
time_t
的{{1}}是32位tm_year
,其最大值为2 31 -1≈2.1* 10 9 < / SUP>
显然,你不能在32位有符号整数中存储~2.9 * 10 11 。当你提出要求时int
正确地失败了。
您可以在this answer中修改gmtime()
的实施,以处理非常大的值。您需要在gmtime()
中解决溢出问题,并将部分SecondsSinceEpoch + 11644473600ULL
和ints
更改为uints
。
答案 1 :(得分:1)
C ++只说gmtime
可能会失败。指定gmtime
在大输入上的行为的标准是POSIX:
如果检测到错误,gmtime()将返回空指针并设置errno以指示错误。
错误
如果出现以下情况,gmtime()和gmtime_r()函数将失败:
[EOVERFLOW] 结果无法表示。
它没有直接说出限制是什么,虽然它确实说如果自纪元以来的秒数为负数,它们与实际时间的关系为undefined。
作为替代方案,请尝试提升
auto testgmtime = [](std::time_t time)
{
std::cout << boost::posix_time::from_time_t(time) << '\n';
};
(虽然在我的linux设置上,from_time_t()似乎比gmtime更早达到了上限)