summaryrefslogtreecommitdiffstats
path: root/src/corelib/time
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2024-04-10 16:41:13 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2024-04-19 13:56:36 +0200
commitfccf6cfdd2f32b15288984d11648ac51f338c62a (patch)
tree288c28c2f263f4e9e19318300079f8047527d610 /src/corelib/time
parent7aada633be93f581f32079610cb3db9800680449 (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>
Diffstat (limited to 'src/corelib/time')
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp16
-rw-r--r--src/corelib/time/qtimezoneprivate_android.cpp13
-rw-r--r--src/corelib/time/qtimezoneprivate_icu.cpp8
-rw-r--r--src/corelib/time/qtimezoneprivate_mac.mm4
-rw-r--r--src/corelib/time/qtimezoneprivate_p.h16
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp76
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp10
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) {