std :: tm或std :: gmtime的限制是什么?

时间:2012-07-15 03:49:11

标签: c++

当我通过最大可能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是不是很糟糕?我可以使用哪种替代工作

2 个答案:

答案 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 + 11644473600ULLints更改为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更早达到了上限)

相关问题