diff options
Diffstat (limited to 'src/corelib/time/qtimezoneprivate.cpp')
-rw-r--r-- | src/corelib/time/qtimezoneprivate.cpp | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp index facdf6661d..244ebbb07c 100644 --- a/src/corelib/time/qtimezoneprivate.cpp +++ b/src/corelib/time/qtimezoneprivate.cpp @@ -356,26 +356,33 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, // Check we do *really* have transitions for this zone: if (tran.atMSecsSinceEpoch != invalidMSecs()) { - - /* - So now tran is definitely before and nextTran is either after or only - slightly before. One is standard time; we interpret the other as DST - (although the transition might in fact by a change in standard offset). Our - hint tells us which of those to use (defaulting to standard if no hint): try - it first; if that fails, try the other; if both fail, life's tricky. - */ + /* So now tran is definitely before ... */ Q_ASSERT(forLocalMSecs < 0 || forLocalMSecs - tran.offsetFromUtc * 1000 > tran.atMSecsSinceEpoch); + // Work out the UTC value it would make sense to return if using tran: + tran.atMSecsSinceEpoch = forLocalMSecs - tran.offsetFromUtc * 1000; + // If we know of no transition after it, the answer is easy: const qint64 nextStart = nextTran.atMSecsSinceEpoch; - // Work out the UTC values it might make sense to return: + if (nextStart == invalidMSecs()) + return tran; + + /* + ... and nextTran is either after or only slightly before. We're + going to interpret one as standard time, the other as DST + (although the transition might in fact be a change in standard + offset, or a change in DST offset, e.g. to/from double-DST). Our + hint tells us which of those to use (defaulting to standard if no + hint): try it first; if that fails, try the other; if both fail, + life's tricky. + */ + // Work out the UTC value it would make sense to return if using nextTran: nextTran.atMSecsSinceEpoch = forLocalMSecs - nextTran.offsetFromUtc * 1000; - tran.atMSecsSinceEpoch = forLocalMSecs - tran.offsetFromUtc * 1000; // If both or neither have zero DST, treat the one with lower offset as standard: const bool nextIsDst = !nextTran.daylightTimeOffset == !tran.daylightTimeOffset ? tran.offsetFromUtc < nextTran.offsetFromUtc : nextTran.daylightTimeOffset; // If that agrees with hint > 0, our first guess is to use nextTran; else tran. - const bool nextFirst = nextIsDst == (hint > 0) && nextStart != invalidMSecs(); + const bool nextFirst = nextIsDst == (hint > 0); for (int i = 0; i < 2; i++) { /* On the first pass, the case we consider is what hint told us to expect @@ -384,12 +391,11 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, by which time the second case, that we're trying, is likely right. */ if (nextFirst ? i == 0 : i) { - Q_ASSERT(nextStart != invalidMSecs()); if (nextStart <= nextTran.atMSecsSinceEpoch) return nextTran; } else { // If next is invalid, nextFirst is false, to route us here first: - if (nextStart == invalidMSecs() || nextStart > tran.atMSecsSinceEpoch) + if (nextStart > tran.atMSecsSinceEpoch) return tran; } } @@ -663,12 +669,25 @@ bool QTimeZonePrivate::isValidId(const QByteArray &ianaId) return true; } -QString QTimeZonePrivate::isoOffsetFormat(int offsetFromUtc) +QString QTimeZonePrivate::isoOffsetFormat(int offsetFromUtc, QTimeZone::NameType mode) { - const int mins = offsetFromUtc / 60; - return QString::fromUtf8("UTC%1%2:%3").arg(mins >= 0 ? QLatin1Char('+') : QLatin1Char('-')) - .arg(qAbs(mins) / 60, 2, 10, QLatin1Char('0')) - .arg(qAbs(mins) % 60, 2, 10, QLatin1Char('0')); + if (mode == QTimeZone::ShortName && !offsetFromUtc) + return utcQString(); + + char sign = '+'; + if (offsetFromUtc < 0) { + sign = '-'; + offsetFromUtc = -offsetFromUtc; + } + const int secs = offsetFromUtc % 60; + const int mins = (offsetFromUtc / 60) % 60; + const int hour = offsetFromUtc / 3600; + QString result = QString::asprintf("UTC%c%02d", sign, hour); + if (mode != QTimeZone::ShortName || secs || mins) + result += QString::asprintf(":%02d", mins); + if (mode == QTimeZone::LongName || secs) + result += QString::asprintf(":%02d", secs); + return result; } QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id) @@ -801,13 +820,7 @@ qint64 QUtcTimeZonePrivate::offsetFromUtcString(const QByteArray &id) // Create offset from UTC QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds) { - QString utcId; - - if (offsetSeconds == 0) - utcId = utcQString(); - else - utcId = isoOffsetFormat(offsetSeconds); - + QString utcId = isoOffsetFormat(offsetSeconds, QTimeZone::ShortName); init(utcId.toUtf8(), offsetSeconds, utcId, utcId, QLocale::AnyCountry, utcId); } |