diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2024-04-10 16:41:13 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2024-04-19 13:56:36 +0200 |
commit | fccf6cfdd2f32b15288984d11648ac51f338c62a (patch) | |
tree | 288c28c2f263f4e9e19318300079f8047527d610 | |
parent | 7aada633be93f581f32079610cb3db9800680449 (diff) |
Make QTimeZonePrivate::Data construction easier
Turn QTZP::invalidData() into a default constructor. A second
constructor taking needed details avoids exercising that default
constructor elsewhere, when the invalid values aren't what we
need. All constructed instances now have all members initialized.
In the TZ backend, add some PosixZone helpers to create Data objects,
reducing the complexity of calculatePosixTransitions().
Task-number: QTBUG-122619
Change-Id: I56557a2f6249d60012355d5d72c662474be76e51
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
-rw-r--r-- | src/corelib/time/qtimezoneprivate.cpp | 16 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_android.cpp | 13 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_icu.cpp | 8 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_mac.mm | 4 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_p.h | 16 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_tz.cpp | 76 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_win.cpp | 10 |
7 files changed, 71 insertions, 72 deletions
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp index 861ebefbdf..8d0cb80a18 100644 --- a/src/corelib/time/qtimezoneprivate.cpp +++ b/src/corelib/time/qtimezoneprivate.cpp @@ -230,7 +230,7 @@ bool QTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const QTimeZonePrivate::Data QTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { Q_UNUSED(forMSecsSinceEpoch); - return invalidData(); + return {}; } // Private only method for use by QDateTime to convert local msecs to epoch msecs @@ -489,13 +489,13 @@ bool QTimeZonePrivate::hasTransitions() const QTimeZonePrivate::Data QTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const { Q_UNUSED(afterMSecsSinceEpoch); - return invalidData(); + return {}; } QTimeZonePrivate::Data QTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const { Q_UNUSED(beforeMSecsSinceEpoch); - return invalidData(); + return {}; } QTimeZonePrivate::DataList QTimeZonePrivate::transitions(qint64 fromMSecsSinceEpoch, @@ -586,16 +586,6 @@ void QTimeZonePrivate::serialize(QDataStream &ds) const // Static Utility Methods -QTimeZonePrivate::Data QTimeZonePrivate::invalidData() -{ - Data data; - data.atMSecsSinceEpoch = invalidMSecs(); - data.offsetFromUtc = invalidSeconds(); - data.standardTimeOffset = invalidSeconds(); - data.daylightTimeOffset = invalidSeconds(); - return data; -} - QTimeZone::OffsetData QTimeZonePrivate::invalidOffsetData() { QTimeZone::OffsetData offsetData; diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp index 0194352f5e..47fc68b1ac 100644 --- a/src/corelib/time/qtimezoneprivate_android.cpp +++ b/src/corelib/time/qtimezoneprivate_android.cpp @@ -182,16 +182,11 @@ bool QAndroidTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const QTimeZonePrivate::Data QAndroidTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { if (androidTimeZone.isValid()) { - Data data; - data.atMSecsSinceEpoch = forMSecsSinceEpoch; - data.standardTimeOffset = standardTimeOffset(forMSecsSinceEpoch); - data.offsetFromUtc = offsetFromUtc(forMSecsSinceEpoch); - data.daylightTimeOffset = data.offsetFromUtc - data.standardTimeOffset; - data.abbreviation = abbreviation(forMSecsSinceEpoch); - return data; - } else { - return invalidData(); + return Data(abbreviation(forMSecsSinceEpoch), forMSecsSinceEpoch, + offsetFromUtc(forMSecsSinceEpoch), + standardTimeOffset(forMSecsSinceEpoch)); } + return {}; } // java.util.TimeZone does not directly provide transitions, diff --git a/src/corelib/time/qtimezoneprivate_icu.cpp b/src/corelib/time/qtimezoneprivate_icu.cpp index 2a2770d3ea..1a3baa70d0 100644 --- a/src/corelib/time/qtimezoneprivate_icu.cpp +++ b/src/corelib/time/qtimezoneprivate_icu.cpp @@ -153,7 +153,7 @@ static QTimeZonePrivate::Data ucalTimeZoneTransition(UCalendar *m_ucal, UTimeZoneTransitionType type, qint64 atMSecsSinceEpoch) { - QTimeZonePrivate::Data tran = QTimeZonePrivate::invalidData(); + QTimeZonePrivate::Data tran; // Clone the ucal so we don't change the shared object UErrorCode status = U_ZERO_ERROR; @@ -384,7 +384,7 @@ bool QIcuTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const QTimeZonePrivate::Data QIcuTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { // Available in ICU C++ api, and draft C api in v50 - QTimeZonePrivate::Data data = invalidData(); + QTimeZonePrivate::Data data; #if U_ICU_VERSION_MAJOR_NUM >= 50 data = ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE, forMSecsSinceEpoch); @@ -417,7 +417,7 @@ QTimeZonePrivate::Data QIcuTimeZonePrivate::nextTransition(qint64 afterMSecsSinc return ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_NEXT, afterMSecsSinceEpoch); #else Q_UNUSED(afterMSecsSinceEpoch); - return invalidData(); + return {}; #endif } @@ -428,7 +428,7 @@ QTimeZonePrivate::Data QIcuTimeZonePrivate::previousTransition(qint64 beforeMSec return ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_PREVIOUS, beforeMSecsSinceEpoch); #else Q_UNUSED(beforeMSecsSinceEpoch); - return invalidData(); + return {}; #endif } diff --git a/src/corelib/time/qtimezoneprivate_mac.mm b/src/corelib/time/qtimezoneprivate_mac.mm index 8bc48f893b..da7e24d614 100644 --- a/src/corelib/time/qtimezoneprivate_mac.mm +++ b/src/corelib/time/qtimezoneprivate_mac.mm @@ -190,7 +190,7 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinc const NSTimeInterval nextSecs = nextDate.timeIntervalSince1970; if (nextDate == nil || nextSecs <= seconds) { [nextDate release]; - return invalidData(); + return {}; } tran.atMSecsSinceEpoch = nextSecs * 1000; tran.offsetFromUtc = [m_nstz secondsFromGMTForDate:nextDate]; @@ -273,7 +273,7 @@ QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSec return data(qint64(prevSecs * 1e3)); // No transition data; or first transition later than requested time. - return invalidData(); + return {}; } QByteArray QMacTimeZonePrivate::systemTimeZoneId() const diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h index 53da9693ca..4ad51f44e7 100644 --- a/src/corelib/time/qtimezoneprivate_p.h +++ b/src/corelib/time/qtimezoneprivate_p.h @@ -44,13 +44,26 @@ QT_BEGIN_NAMESPACE class Q_AUTOTEST_EXPORT QTimeZonePrivate : public QSharedData { public: - //Version of QTimeZone::OffsetData struct using msecs for efficiency + // Version of QTimeZone::OffsetData struct using msecs for efficiency struct Data { QString abbreviation; qint64 atMSecsSinceEpoch; int offsetFromUtc; int standardTimeOffset; int daylightTimeOffset; + Data() + : atMSecsSinceEpoch(QTimeZonePrivate::invalidMSecs()), + offsetFromUtc(QTimeZonePrivate::invalidSeconds()), + standardTimeOffset(QTimeZonePrivate::invalidSeconds()), + daylightTimeOffset(QTimeZonePrivate::invalidSeconds()) + {} + Data(const QString &name, qint64 when, int offset, int standard) + : abbreviation(name), + atMSecsSinceEpoch(when), + offsetFromUtc(offset), + standardTimeOffset(standard), + daylightTimeOffset(offset - standard) + {} }; typedef QList<Data> DataList; @@ -112,7 +125,6 @@ public: { return (std::numeric_limits<qint64>::min)(); } [[nodiscard]] static constexpr qint64 invalidSeconds() { return (std::numeric_limits<int>::min)(); } - static Data invalidData(); static QTimeZone::OffsetData invalidOffsetData(); static QTimeZone::OffsetData toOffsetData(const Data &data); static bool isValidId(const QByteArray &ianaId); diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp index 8c6a32edc9..fce9deaa33 100644 --- a/src/corelib/time/qtimezoneprivate_tz.cpp +++ b/src/corelib/time/qtimezoneprivate_tz.cpp @@ -523,6 +523,16 @@ struct PosixZone QString name; int offset = InvalidOffset; bool hasValidOffset() const noexcept { return offset != InvalidOffset; } + QTimeZonePrivate::Data dataAt(qint64 when) + { + Q_ASSERT(hasValidOffset()); + return QTimeZonePrivate::Data(name, when, offset, offset); + } + QTimeZonePrivate::Data dataAtOffset(qint64 when, int standard) + { + Q_ASSERT(hasValidOffset()); + return QTimeZonePrivate::Data(name, when, offset, standard); + } static PosixZone parse(const char *&pos, const char *end); }; @@ -663,13 +673,9 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray // If only the name part, or no DST specified, then no transitions if (parts.size() == 1 || !dstZone.hasValidOffset()) { - QTimeZonePrivate::Data data; - data.atMSecsSinceEpoch = lastTranMSecs; - data.offsetFromUtc = stdZone.offset; - data.standardTimeOffset = stdZone.offset; - data.daylightTimeOffset = 0; - data.abbreviation = stdZone.name.isEmpty() ? QString::fromUtf8(parts.at(0)) : stdZone.name; - result << data; + result.emplaceBack( + stdZone.name.isEmpty() ? QString::fromUtf8(parts.at(0)) : stdZone.name, + lastTranMSecs, stdZone.offset, stdZone.offset); return result; } if (parts.size() < 3 || parts.at(1).isEmpty() || parts.at(2).isEmpty()) @@ -702,40 +708,33 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray // moments; the atMSecsSinceEpoch values computed from them are // correctly offse to be UTC-based. - QTimeZonePrivate::Data dstData; // Transition to DST + // Transition to daylight-saving time: QDateTime dst(calculatePosixDate(dstDateRule, year) .startOfDay(QTimeZone::UTC).addSecs(dstTime)); - dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - stdZone.offset * 1000; - dstData.offsetFromUtc = dstZone.offset; - dstData.standardTimeOffset = stdZone.offset; - dstData.daylightTimeOffset = dstZone.offset - stdZone.offset; - dstData.abbreviation = dstZone.name; - QTimeZonePrivate::Data stdData; // Transition to standard time + auto saving = dstZone.dataAtOffset(dst.toMSecsSinceEpoch() - stdZone.offset * 1000, + stdZone.offset); + // Transition to standard time: QDateTime std(calculatePosixDate(stdDateRule, year) .startOfDay(QTimeZone::UTC).addSecs(stdTime)); - stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - dstZone.offset * 1000; - stdData.offsetFromUtc = stdZone.offset; - stdData.standardTimeOffset = stdZone.offset; - stdData.daylightTimeOffset = 0; - stdData.abbreviation = stdZone.name; + auto standard = stdZone.dataAt(std.toMSecsSinceEpoch() - dstZone.offset * 1000); if (year == startYear) { // Handle the special case of fixed state, which may be represented // by fake transitions at start and end of each year: - if (dstData.atMSecsSinceEpoch < stdData.atMSecsSinceEpoch) { + if (saving.atMSecsSinceEpoch < standard.atMSecsSinceEpoch) { if (dst <= QDate(year, 1, 1).startOfDay(QTimeZone::UTC) && std >= QDate(year, 12, 31).endOfDay(QTimeZone::UTC)) { // Permanent DST: - dstData.atMSecsSinceEpoch = lastTranMSecs; - result << dstData; + saving.atMSecsSinceEpoch = lastTranMSecs; + result.emplaceBack(std::move(saving)); return result; } } else { if (std <= QDate(year, 1, 1).startOfDay(QTimeZone::UTC) && dst >= QDate(year, 12, 31).endOfDay(QTimeZone::UTC)) { // Permanent Standard time, perversely described: - stdData.atMSecsSinceEpoch = lastTranMSecs; - result << stdData; + standard.atMSecsSinceEpoch = lastTranMSecs; + result.emplaceBack(std::move(standard)); return result; } } @@ -744,14 +743,17 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray const bool useStd = std.isValid() && std.date().year() == year && !stdZone.name.isEmpty(); const bool useDst = dst.isValid() && dst.date().year() == year && !dstZone.name.isEmpty(); if (useStd && useDst) { - if (dst < std) - result << dstData << stdData; - else - result << stdData << dstData; + if (dst < std) { + result.emplaceBack(std::move(saving)); + result.emplaceBack(std::move(standard)); + } else { + result.emplaceBack(std::move(standard)); + result.emplaceBack(std::move(saving)); + } } else if (useStd) { - result << stdData; + result.emplaceBack(std::move(standard)); } else if (useDst) { - result << dstData; + result.emplaceBack(std::move(saving)); } } return result; @@ -1137,8 +1139,8 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime QTimeZonePrivate::Data QTzTimeZonePrivate::dataFromRule(QTzTransitionRule rule, qint64 msecsSinceEpoch) const { - return { QString::fromUtf8(cached_data.m_abbreviations.at(rule.abbreviationIndex)), - msecsSinceEpoch, rule.stdOffset + rule.dstOffset, rule.stdOffset, rule.dstOffset }; + return Data(QString::fromUtf8(cached_data.m_abbreviations.at(rule.abbreviationIndex)), + msecsSinceEpoch, rule.stdOffset + rule.dstOffset, rule.stdOffset); } QList<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const @@ -1168,7 +1170,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const } } if (tranCache().isEmpty()) // Only possible if !isValid() - return invalidData(); + return {}; // Otherwise, use the rule for the most recent or first transition: auto last = std::partition_point(tranCache().cbegin(), tranCache().cend(), @@ -1199,7 +1201,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch; }); - return it == posixTrans.cend() ? invalidData() : *it; + return it == posixTrans.cend() ? Data{} : *it; } // Otherwise, if we can find a valid tran, use its rule: @@ -1207,7 +1209,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince [afterMSecsSinceEpoch] (const QTzTransitionTime &at) { return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch; }); - return last != tranCache().cend() ? dataForTzTransition(*last) : invalidData(); + return last != tranCache().cend() ? dataForTzTransition(*last) : Data{}; } QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const @@ -1224,7 +1226,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs if (it > posixTrans.cbegin()) return *--it; // It fell between the last transition (if any) and the first of the POSIX rule: - return tranCache().isEmpty() ? invalidData() : dataForTzTransition(tranCache().last()); + return tranCache().isEmpty() ? Data{} : dataForTzTransition(tranCache().last()); } // Otherwise if we can find a valid tran then use its rule @@ -1232,7 +1234,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs [beforeMSecsSinceEpoch] (const QTzTransitionTime &at) { return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch; }); - return last > tranCache().cbegin() ? dataForTzTransition(*--last) : invalidData(); + return last > tranCache().cbegin() ? dataForTzTransition(*--last) : Data{}; } bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp index 2502516810..7874c22174 100644 --- a/src/corelib/time/qtimezoneprivate_win.cpp +++ b/src/corelib/time/qtimezoneprivate_win.cpp @@ -692,7 +692,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons // Fell off start of rule, try previous rule. } // We don't have relevant data :-( - return invalidData(); + return {}; } bool QWinTimeZonePrivate::hasTransitions() const @@ -774,13 +774,13 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc } } // Apparently no transition after the given time: - return invalidData(); + return {}; } QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const { if (beforeMSecsSinceEpoch <= minMSecs()) - return invalidData(); + return {}; int year = msecsToDate(beforeMSecsSinceEpoch).year(); for (int ruleIndex = ruleIndexForYear(m_tranRules, year); @@ -830,7 +830,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec } } // Apparently no transition before the given time: - return invalidData(); + return {}; } QByteArray QWinTimeZonePrivate::systemTimeZoneId() const @@ -866,7 +866,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::ruleToData(const QWinTransitionRule QTimeZone::TimeType type, bool fakeDst) const { - Data tran = invalidData(); + Data tran; tran.atMSecsSinceEpoch = atMSecsSinceEpoch; tran.standardTimeOffset = rule.standardTimeBias * -60; if (fakeDst) { |