C++ std::tm或std::gmtime的限制是什么?
C++ std::tm或std::gmtime的限制是什么?,c++,C++,std::gmtime在我通过最大可能std::time\u t时失败。请参阅以下测试: std::cout << "sizeof(std::time_t): " << sizeof(std::time_t) << '\n' << "sizeof(long long): " << sizeof(long long) << '\n' << "sizeof(unsi
std::gmtime
在我通过最大可能std::time\u 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());
我正在使用VS2012。有没有一个我没有看到的标准限制,或者这对我来说很糟糕?我可以使用什么替代方案来工作?C++只说
gmtime
可能会失败。指定大输入时gmtime
行为的标准是:
如果检测到错误,gmtime()将返回空指针并设置errno以指示错误
错误
如果出现以下情况,gmtime()和gmtime_r()函数将失败:
[EOVERFLOW]
结果无法表示
它并没有直接说明极限是多少,虽然它说如果从纪元开始的秒数是负的,那么它们与实际时间的关系是负的
另一种选择是尝试boost
auto testgmtime = [](std::time_t time)
{
std::cout << boost::posix_time::from_time_t(time) << '\n';
};
autotestgmtime=[](标准::时间\u t时间)
{
std::coutVS2012并不是垃圾。算算一下
如果time\u t
是64位整数,则其中的最大秒数为264-1(如果是无符号整数),或263-1(如果是有符号整数)
大约263秒对应263/(60*60*24*365)≈ 2.9*1011年
time\t
的tm\u year
是一个32位的int
,其最大值为231-1≈ 2.1*109
显然,您不能将~2.9*1011存储在32位有符号整数中。而且当您要求时,gmtime()
理所当然地会失败
您可以在中修改我的gmtime()
实现以处理非常大的值。您需要解决SecondsSinceEpoch+1164473600ull
中的溢出问题,并将一些int
和uint
更改为uint64s
,谢谢,这确实解释了非常高的数字。但是(标准::数值限制::max()-1)/10000000也失败了,这只会是一个29247年的范围,2924年的范围也是如此,最后292年的范围起作用了。我不知道它到底停在哪里,但这个东西在300到3000年之间就失败了。我想我必须写我自己的东西,就像你建议的那样。你可以用二进制搜索来确定截止日期/时间。我很好奇让我们知道它是什么。它可能揭示了逻辑。~300到~3000年将需要33到37位。我想知道,尽管时间是64位,但实现是否基本上是32位的(请注意,您可以选择时间大小)。根据
auto testgmtime = [](std::time_t time)
{
std::cout << boost::posix_time::from_time_t(time) << '\n';
};