diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index 72456498554..0d0da82ae0a 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -833,7 +833,7 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, i QString sectiontext = sectionTextRef.toString(); int num = 0, used = 0; if (sn.type == MonthSection) { - const QDate minDate = getMinimum().date(); + const QDate minDate = getMinimum(currentValue.timeRepresentation()).date(); const int year = currentValue.date().year(calendar); const int min = (year == minDate.year(calendar)) ? minDate.month(calendar) : 1; num = findMonth(sectiontext.toLower(), min, sectionIndex, year, §iontext, &used); @@ -1489,8 +1489,8 @@ QDateTimeParser::StateNode QDateTimeParser::parse(const QString &input, int position, const QDateTime &defaultValue, bool fixup) const { - const QDateTime minimum = getMinimum(); - const QDateTime maximum = getMaximum(); + const QDateTime minimum = getMinimum(defaultValue.timeRepresentation()); + const QDateTime maximum = getMaximum(defaultValue.timeRepresentation()); m_text = input; QDTPDEBUG << "parse" << input; @@ -2147,8 +2147,8 @@ bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, QSt int max = absoluteMax(index, current); // Time-zone field is only numeric if given as offset from UTC: if (node.type != TimeZoneSection || current.timeSpec() == Qt::OffsetFromUTC) { - const QDateTime maximum = getMaximum(); - const QDateTime minimum = getMinimum(); + const QDateTime maximum = getMaximum(current.timeRepresentation()); + const QDateTime minimum = getMinimum(current.timeRepresentation()); // Range from minimum to maximum might not contain current if an earlier // field's value was full-width but out of range. In such a case the // parse is already headed for Invalid, so it doesn't matter that we get @@ -2225,9 +2225,9 @@ QString QDateTimeParser::stateName(State s) const QDateTime QDateTimeParser::baseDate(const QTimeZone &zone) const { QDateTime when = QDate(defaultCenturyStart, 1, 1).startOfDay(zone); - if (const QDateTime start = getMinimum(); when < start) + if (const QDateTime start = getMinimum(zone); when < start) return start; - if (const QDateTime end = getMaximum(); when > end) + if (const QDateTime end = getMaximum(zone); when > end) return end; return when; } @@ -2268,18 +2268,28 @@ bool QDateTimeParser::fromString(const QString &t, QDateTime *datetime, int base return tmp.state >= Intermediate && !tmp.conflicts && tmp.value.isValid(); } -QDateTime QDateTimeParser::getMinimum() const +QDateTime QDateTimeParser::getMinimum(const QTimeZone &zone) const { // NB: QDateTimeParser always uses Qt::LocalTime time spec by default. If // any subclass needs a changing time spec, it must override this // method. At the time of writing, this is done by QDateTimeEditPrivate. - // Cache the only case + // Cache the only case (and make sure it knows its UTC offset): static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN.startOfDay()); - return localTimeMin; + static const QDateTime utcTimeMin = localTimeMin.toUTC(); + switch (zone.timeSpec()) { + case Qt::LocalTime: + return localTimeMin; + case Qt::UTC: + return utcTimeMin; + case Qt::OffsetFromUTC: + case Qt::TimeZone: + break; + } + return utcTimeMin.toTimeZone(zone); } -QDateTime QDateTimeParser::getMaximum() const +QDateTime QDateTimeParser::getMaximum(const QTimeZone &zone) const { // NB: QDateTimeParser always uses Qt::LocalTime time spec by default. If // any subclass needs a changing time spec, it must override this @@ -2287,7 +2297,17 @@ QDateTime QDateTimeParser::getMaximum() const // Cache the only case static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX.endOfDay()); - return localTimeMax; + static const QDateTime utcTimeMax = localTimeMax.toUTC(); + switch (zone.timeSpec()) { + case Qt::LocalTime: + return localTimeMax; + case Qt::UTC: + return utcTimeMax; + case Qt::OffsetFromUTC: + case Qt::TimeZone: + break; + } + return utcTimeMax.toTimeZone(zone); } QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const diff --git a/src/corelib/time/qdatetimeparser_p.h b/src/corelib/time/qdatetimeparser_p.h index dd922bc6276..8539bace69d 100644 --- a/src/corelib/time/qdatetimeparser_p.h +++ b/src/corelib/time/qdatetimeparser_p.h @@ -24,6 +24,7 @@ #include "QtCore/qlist.h" #include "QtCore/qlocale.h" #include "QtCore/qstringlist.h" +#include "QtCore/qtimezone.h" #ifndef QT_BOOTSTRAPPED # include "QtCore/qvariant.h" #endif @@ -229,8 +230,8 @@ protected: // for the benefit of QDateTimeEditPrivate } QString stateName(State s) const; - virtual QDateTime getMinimum() const; - virtual QDateTime getMaximum() const; + virtual QDateTime getMinimum(const QTimeZone &zone) const; + virtual QDateTime getMaximum(const QTimeZone &zone) const; virtual int cursorPosition() const { return -1; } virtual QLocale locale() const { return defaultLocale; } diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index a9b5babde58..c4094264f14 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1820,26 +1820,30 @@ void QDateTimeEditPrivate::updateEdit() } } -QDateTime QDateTimeEditPrivate::getMinimum() const +QDateTime QDateTimeEditPrivate::getMinimum(const QTimeZone &zone) const { if (keyboardTracking) - return minimum.toDateTime(); + return minimum.toDateTime().toTimeZone(zone); + // QDTP's min is the local-time start of QDATETIMEEDIT_DATE_MIN, cached + // (along with its conversion to UTC). if (timeZone.timeSpec() == Qt::LocalTime) - return QDateTimeParser::getMinimum(); + return QDateTimeParser::getMinimum(zone); - return QDATETIMEEDIT_DATE_MIN.startOfDay(timeZone); + return QDATETIMEEDIT_DATE_MIN.startOfDay(timeZone).toTimeZone(zone); } -QDateTime QDateTimeEditPrivate::getMaximum() const +QDateTime QDateTimeEditPrivate::getMaximum(const QTimeZone &zone) const { if (keyboardTracking) - return maximum.toDateTime(); + return maximum.toDateTime().toTimeZone(zone); + // QDTP's max is the local-time end of QDATETIMEEDIT_DATE_MAX, cached + // (along with its conversion to UTC). if (timeZone.timeSpec() == Qt::LocalTime) - return QDateTimeParser::getMaximum(); + return QDateTimeParser::getMaximum(zone); - return QDATETIMEEDIT_DATE_MAX.endOfDay(timeZone); + return QDATETIMEEDIT_DATE_MAX.endOfDay(timeZone).toTimeZone(zone); } /*! diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index f93afd1519a..7b9109692d0 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -61,8 +61,8 @@ public: // Override QDateTimeParser: QString displayText() const override { return edit->text(); } - QDateTime getMinimum() const override; - QDateTime getMaximum() const override; + QDateTime getMinimum(const QTimeZone &zone) const override; + QDateTime getMaximum(const QTimeZone &zone) const override; QLocale locale() const override { return q_func()->locale(); } int cursorPosition() const override { return edit ? edit->cursorPosition() : -1; }