2016-11-22 3170 views
2

我發現奇怪的行爲在Qt 4.8的QDateTime關於fromMSecsSinceEpoch。下面的代碼不會產生結果我希望: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。 的docQDateTime::fromMSecsSinceEpoch(qint64 msecs)明確規定:

有對於處在外QDateTime的有效範圍內,負和正毫秒可能的值。這個函數的行爲對於這些值是未定義的。

但是,沒有任何關於有效範圍的明確聲明。

我發現這個Qt bug report關於Qt 5.5.1,5.6.0和5.7.0 Beta中的時區問題。 我不確定這是否是一個類似的錯誤,或者我提供給QDateTime::fromMSecsSinceEpoch(qint64 msecs)的值是無效的。

什麼是(或者說應該是)可以傳遞給該函數的最大值併產生正確的行爲?

+0

有效日期_The範圍是從1月2日,4713 BCE,到某個時候在今年的1 100 CE_ – Danh

+0

,我讀了,但它不給出一個確切值 – sigy

+1

文檔沒有給出一個確切的數值,這是附近某處'11'000'000 * 365 * 3600 * 1000' – Danh

回答

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,有效日期從1月2日,4713公元前開始,去,直到QDate::toJulianDay()溢出:2^31 days(對於有符號整數最大值)產生近5 000 000 years。這是185 542 587 187 200 000 ms(從公元前4713年1月2日,而不是從時代),「小」超過2^57

編輯:

在評論中討論後,你檢查Qt4.8來源,發現fromMSecsSinceEpoch()使用QDate(1970, 1, 1).addDays(ddays)內部,其中的天數是直接從msecs參數計算。

由於ddays的類型爲int,因此對於大於2^31的值會發生溢出。

+0

我做了一個二分查找,它看起來像傳遞給'fromMSecsSinceEpoch()'的最大有效值是'185542587187199999',它產生_Fr。 7月11日23:59:59 5881580_以UTC計算,遠離1100萬CE。 – sigy

+0

好的,那支持我的二進制搜索結果。然而,正如文件所述,它仍然不是在公元1100萬年前的某個日期。那麼這是文檔的問題嗎? – sigy

+1

看起來像是。該文檔在Qt5中有變化(請參閱[這裏](https://doc.qt.io/qt-5/qdatetime.html#range-of-valid-dates)),所以我無法查看Qt5代碼我必須找到一個完整的答案。你將不得不看看你的Qt4的來源。如果你想/需要更進一步(在這裏隨意分享結果,所以我可以更新我的答案;)) – wasthishelpful