Avoid overflow for date-time in the first (partly) representable day

Computing the start of the first day's number of milliseconds since
the epoch overflows, but adding enough seconds within the day would
have brought us back inside the representable range. So, for days
before the epoch, add a negative number of milliseconds from the end
of the next day instead of a positive number of milliseconds from the
(possibly unrepresentable) start of the target day.  This is another a
follow-up to commit 2b26dea51b

Change-Id: I2e0c68d7012db85dfe7da4a8a20ba95368178ed1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Edward Welbourne 2021-11-10 13:39:25 +01:00
parent 6845c444d0
commit 453695ec92
1 changed files with 10 additions and 2 deletions

View File

@ -278,8 +278,16 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
inline bool timeToMSecs(QDate date, QTime time, qint64 *msecs)
{
qint64 dayms = 0;
return mul_overflow(date.toJulianDay() - JULIAN_DAY_FOR_EPOCH, std::integral_constant<qint64, MSECS_PER_DAY>(), &dayms)
|| add_overflow(dayms, qint64(time.msecsSinceStartOfDay()), msecs);
qint64 daySinceEpoch = date.toJulianDay() - JULIAN_DAY_FOR_EPOCH;
qint64 msInDay = time.msecsSinceStartOfDay();
if (daySinceEpoch < 0 && msInDay > 0) {
// In the earliest day with representable parts, take care to not
// underflow before an addition that would have fixed it.
++daySinceEpoch;
msInDay -= MSECS_PER_DAY;
}
return mul_overflow(daySinceEpoch, std::integral_constant<qint64, MSECS_PER_DAY>(), &dayms)
|| add_overflow(dayms, msInDay, msecs);
}
qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)