summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-04-28 15:08:50 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-04-29 14:13:23 +0200
commitae5d40e67407776d57ff06a6717e3d4bbefeaa66 (patch)
tree77dcec9350738b25e2af41038ed66e228fb18776 /src/corelib
parent8ec07b4afc93160e15c1aaa746fd027f2d37f70e (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.cpp56
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)