Rearrange mapLocalTime() so its millis always have the right sign
Doing a simple division to get seconds, before using rounding-down division to get days and positive seconds, saves the need to check for seconds and millis in opposite directions that might cause a needless overflow when computing the final result. Change-Id: Ia4f95bb0510eb4f2c1f9131a34d317bd41bbed2a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
854cb55987
commit
0acb56518d
@ -348,11 +348,13 @@ QString localTimeAbbbreviationAt(qint64 local, QDateTimePrivate::DaylightStatus
|
||||
|
||||
QDateTimePrivate::ZoneState mapLocalTime(qint64 local, QDateTimePrivate::DaylightStatus dst)
|
||||
{
|
||||
const qint64 localDays = QRoundingDown::qDiv(local, MSECS_PER_DAY);
|
||||
qint64 millis = local - localDays * MSECS_PER_DAY;
|
||||
Q_ASSERT(0 <= millis && millis < MSECS_PER_DAY); // Definition of QRD::qDiv.
|
||||
struct tm tmLocal = timeToTm(localDays, int(millis / MSECS_PER_SEC), dst);
|
||||
millis %= MSECS_PER_SEC;
|
||||
qint64 localSecs = local / MSECS_PER_SEC;
|
||||
qint64 millis = local - localSecs * MSECS_PER_SEC; // 0 or with same sign as local
|
||||
const qint64 localDays = QRoundingDown::qDiv(localSecs, SECS_PER_DAY);
|
||||
qint64 daySecs = localSecs - localDays * SECS_PER_DAY;
|
||||
Q_ASSERT(0 <= daySecs && daySecs < SECS_PER_DAY); // Definition of QRD::qDiv.
|
||||
|
||||
struct tm tmLocal = timeToTm(localDays, daySecs, dst);
|
||||
time_t utcSecs;
|
||||
if (!callMkTime(&tmLocal, &utcSecs))
|
||||
return {local};
|
||||
@ -368,22 +370,21 @@ QDateTimePrivate::ZoneState mapLocalTime(qint64 local, QDateTimePrivate::Dayligh
|
||||
&jd))) {
|
||||
return {local, offset, dst, false};
|
||||
}
|
||||
qint64 daySecs = tmSecsWithinDay(tmLocal);
|
||||
daySecs = tmSecsWithinDay(tmLocal);
|
||||
Q_ASSERT(0 <= daySecs && daySecs < SECS_PER_DAY);
|
||||
if (daySecs > 0 && jd < JULIAN_DAY_FOR_EPOCH) {
|
||||
++jd;
|
||||
daySecs -= SECS_PER_DAY;
|
||||
}
|
||||
qint64 localSecs;
|
||||
if (Q_UNLIKELY(daysAndSecondsOverflow(jd, daySecs, &localSecs)))
|
||||
return {local, offset, dst, false};
|
||||
|
||||
offset = localSecs - utcSecs;
|
||||
|
||||
if (localSecs < 0 && millis > 0) {
|
||||
++localSecs;
|
||||
millis -= MSECS_PER_SEC;
|
||||
}
|
||||
// The only way localSecs and millis can now have opposite sign is for
|
||||
// resolution of the local time to have kicked us across the epoch, in which
|
||||
// case there's no danger of overflow. So if overflow is in danger of
|
||||
// happening, we're already doing the best we can to avoid it.
|
||||
qint64 revised;
|
||||
const bool overflow = secondsAndMillisOverflow(localSecs, millis, &revised);
|
||||
return {overflow ? local : revised, offset, dst, !overflow};
|
||||
|
Loading…
Reference in New Issue
Block a user