我在Qt 4.8的QDateTime
中发现了一个关于fromMSecsSinceEpoch
的奇怪行为。以下代码不会产生我期望的结果:
assert(
QDateTime::fromMSecsSinceEpoch(
std::numeric_limits<qint64>::max()
).isValid() == true
);
assert(
QDateTime::fromMSecsSinceEpoch(
std::numeric_limits<qint64>::max()
).toMSecsSinceEpoch() == std::numeric_limits<qint64>::max()
);
虽然第一个断言是真的,但第二个断言失败了。 Qt返回的结果是-210866773624193
。
QDateTime::fromMSecsSinceEpoch(qint64 msecs)
的{{3}}明确指出:
msecs的可能值超出QDateTime的有效范围,包括负数和正数。这些值的行为未定义。
但是,没有任何关于有效范围的明确声明。
我在Qt 5.5.1,5.6.0和5.7.0 Beta中发现了关于时区问题的doc。
我不确定这是一个类似的错误,或者我提供给QDateTime::fromMSecsSinceEpoch(qint64 msecs)
的价值是无效的。
什么是(或者应该是)可以传递给此函数的最大值并产生正确的行为?
答案 0 :(得分:2)
std::numeric_limits<qint64>::max() ms
会产生9 223 372 036 854 775 807 ms
,9 223 372 036 854 775 s
,2 562 047 788 015 hours
,106 751 991 167 days
或292 471 208 years
:这远远超过1100万在有效范围QDateTime
。
从the doc开始,有效日期从公元前4713年1月2日开始,直到QDate::toJulianDay()
溢出:2^31 days
(有符号整数的最大值)几乎为5 000 000 years
。那是185 542 587 187 200 000 ms
(从1月2日,公元前4713年开始,而不是从大纪元开始),比2^57
更“小”。
修改强>
在评论中讨论后,您检查了Qt4.8来源,发现fromMSecsSinceEpoch()
在内部使用QDate(1970, 1, 1).addDays(ddays)
,其中天数直接来自msecs
参数。
由于此处ddays
类型为int
,因此对于大于2^31
的值,这会溢出。