Допустимый диапазон для QDateTime:: fromMSecsSinceEpoch
Я обнаружил странное поведение в QDateTime
Qt 4.8 относительно 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
.
В doc для QDateTime::fromMSecsSinceEpoch(qint64 msecs)
ясно говорится:
Существуют возможные значения для мсек, которые лежат за пределами допустимого диапазона QDateTime, как отрицательные, так и положительные. Поведение этой функции не определено для тех, кто ценности.
Однако нет никакого явного утверждения о допустимом диапазоне.
Я нашел этот отчет об ошибке Qt о проблеме, касающейся часовых поясов в бета-версии Qt 5.5.1, 5.6.0 и 5.7.0.
Я не уверен, что это похожая ошибка, или если значение, которое я предоставил QDateTime::fromMSecsSinceEpoch(qint64 msecs)
, просто недопустимо.
Каково (или, скорее, должно быть) максимальное значение, которое может быть передано этой функции и дает правильное поведение?
1 ответ:
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
: это далеко за пределы 11 миллионов лет в допустимом диапазонеQDateTime
.Изdoc , действительные даты начинаются со 2 января 4713 года до н. э. и идут до переполнения
QDate::toJulianDay()
:2^31 days
(максимальное значение для целого числа со знаком) дает почти5 000 000 years
. Это185 542 587 187 200 000 ms
(от 2 января 4713 года до н. э., а не от эпохи), "немного" больше2^57
.Редактировать:
После обсуждения в комментариях вы проверили источники Qt4. 8 и обнаружил, что
fromMSecsSinceEpoch()
используетQDate(1970, 1, 1).addDays(ddays)
внутренне, где число дней вычисляется непосредственно из параметраmsecs
.Так как
ddays
имеет здесь типint
, это будет переполнение для значений больше, чем2^31
.