Cache UTC versions of QDTP::getM(in,ax)imum()
The static min and max moments of QDateTimeParser are local times. Now that baseDate() needs to check whether the start of the two-year century falls between these, and parsing of simply a date or simply a time (not a date-time) uses UTC, to comparisons involve mapping the local time to UTC, with the usual associated expense. Do that expensive operation once on creation of the min and max local times, so that it'll be cached for use by the comparisons. This shall also help with other comparisons to max and min, so is of use even before the introduction of baseDate(), for all that that change brought the issue to light. Thanks to Jøger Hansegård for analysis of the profiler data that revealed the root cause of a significant slow-down. Pick-to: 6.7 6.5 Fixes: QTBUG-124465 Change-Id: I539c8ae782717635fb722c4573d85bc63073958a Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit b6a11a4ee5319366f14c11c7cf3a4f1dbf33cfd5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
29934f62ef
commit
16abff0f85
@ -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());
|
||||
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());
|
||||
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
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user