diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-04-28 15:08:50 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-04-29 14:13:23 +0200 |
commit | ae5d40e67407776d57ff06a6717e3d4bbefeaa66 (patch) | |
tree | 77dcec9350738b25e2af41038ed66e228fb18776 /src/corelib | |
parent | 8ec07b4afc93160e15c1aaa746fd027f2d37f70e (diff) |
Handle invalid system zone case when falling back from time_t functions
Ammends commit 530e0bd469e6859269c2d1a792b8ce819fbff389, in which I
added a QTimeZone-based fall-back for handling of conversions between
local time and UTC when outside the range supported by time_t-based
functions. That replaced prior kludges, when feature timezone is
enabled; however, even with feature timezone, it's possible for the
system zone to be invalid. So retain the old kludges also as fall-back
for when the system zone is invalid, as well as when we have no
timezones to fall back on.
Change-Id: Ie2b8af7f1a87d7b0e39cc5ac0c04b04d574f84b5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 5b726f0c7c..a61a7d5706 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -2657,19 +2657,22 @@ bool QDateTimePrivate::epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTi #if QT_CONFIG(timezone) // Use the system time-zone. const auto sys = QTimeZone::systemTimeZone(); - if (daylightStatus) { - *daylightStatus = sys.d->isDaylightTime(msecs) - ? QDateTimePrivate::DaylightTime - : QDateTimePrivate::StandardTime; - } + if (sys.isValid()) { + if (daylightStatus) { + *daylightStatus = sys.d->isDaylightTime(msecs) + ? QDateTimePrivate::DaylightTime + : QDateTimePrivate::StandardTime; + } - // NB: cast to qint64 here is important to make sure a matching - // add_overflow is found, GCC 7.5.0 fails without this cast - if (add_overflow(msecs, qint64(sys.d->offsetFromUtc(msecs) * MSECS_PER_SEC), &msecs)) - return false; - msecsToTime(msecs, localDate, localTime); - return true; -#else // Kludge + // NB: cast to qint64 here is important to make sure a matching + // add_overflow is found, GCC 7.5.0 fails without this cast + if (add_overflow(msecs, qint64(sys.d->offsetFromUtc(msecs)) * MSECS_PER_SEC, &msecs)) + return false; + msecsToTime(msecs, localDate, localTime); + return true; + } +#endif // timezone + // Kludge // Use existing method to fake the conversion (this is deeply flawed // as it may apply the conversion from the wrong day number, e.g. if // rule is last Sunday of month). @@ -2686,7 +2689,6 @@ bool QDateTimePrivate::epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTi bool res = qt_localtime(fakeMsecs, localDate, localTime, daylightStatus); *localDate = localDate->addDays(fakeDate.daysTo(utcDate)); return res; -#endif // timezone } // Falls inside time_t supported range so can use localtime @@ -2743,19 +2745,22 @@ qint64 QDateTimePrivate::localMSecsToEpochMSecs(qint64 localMsecs, #if QT_CONFIG(timezone) // Use the system zone: const auto sys = QTimeZone::systemTimeZone(); - const qint64 utcMsecs = - QDateTimePrivate::zoneMSecsToEpochMSecs(localMsecs, sys, - QDateTimePrivate::UnknownDaylightTime, - localDate, localTime); - if (abbreviation) - *abbreviation = sys.d->abbreviation(utcMsecs); - if (daylightStatus) { - *daylightStatus = sys.d->isDaylightTime(utcMsecs) - ? QDateTimePrivate::DaylightTime - : QDateTimePrivate::StandardTime; + if (sys.isValid()) { + const qint64 utcMsecs = + QDateTimePrivate::zoneMSecsToEpochMSecs(localMsecs, sys, + QDateTimePrivate::UnknownDaylightTime, + localDate, localTime); + if (abbreviation && sys.isValid()) + *abbreviation = sys.d->abbreviation(utcMsecs); + if (daylightStatus) { + *daylightStatus = sys.isValid() && sys.d->isDaylightTime(utcMsecs) + ? QDateTimePrivate::DaylightTime + : QDateTimePrivate::StandardTime; + } + return utcMsecs; } - return utcMsecs; -#else // Kludge +#endif // timezone + // Kludge // Use existing method to fake the conversion (this is deeply flawed as it // may apply the conversion from the wrong day number, e.g. if rule is last // Sunday of month). @@ -2777,7 +2782,6 @@ qint64 QDateTimePrivate::localMSecsToEpochMSecs(qint64 localMsecs, QTime utcTime; msecsToTime(utcMsecs, &utcDate, &utcTime); return timeToMSecs(utcDate.addDays(fakeDiff), utcTime); -#endif } static inline bool specCanBeSmall(Qt::TimeSpec spec) |