QDateTime :: fromMSecsSinceEpoch的有效范围

时间:2016-11-22 08:13:19

标签: c++ qt qt5

我在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返回的结果是-210866773624193QDateTime::fromMSecsSinceEpoch(qint64 msecs)的{​​{3}}明确指出:

  

msecs的可能值超出QDateTime的有效范围,包括负数和正数。这些值的行为未定义。

但是,没有任何关于有效范围的明确声明。

我在Qt 5.5.1,5.6.0和5.7.0 Beta中发现了关于时区问题的doc。 我不确定这是一个类似的错误,或者我提供给QDateTime::fromMSecsSinceEpoch(qint64 msecs)的价值是无效的。

什么是(或者应该是)可以传递给此函数的最大值并产生正确的行为?

1 个答案:

答案 0 :(得分:2)

std::numeric_limits<qint64>::max() ms会产生9 223 372 036 854 775 807 ms9 223 372 036 854 775 s2 562 047 788 015 hours106 751 991 167 days292 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的值,这会溢出。