Use UTC when parsing only a date or only a time, not a date-time
This should reduce the amount of fall-out from DST complications. Also document the assumptions of QDateTimeParser's two fromString() methods (and fix the punctuation on the QDateTime parameter). Adjusted some tests to match. Since only QDateTime-returning methods will show the difference, and it's at least somewhat odd to be using those on QDateEdit or QTimeEdit, this should have little impact on API users. [ChangeLog][QtCore][Behavior Change] QDateEdit and QTimeEdit now operate in UTC, to avoid spurious complications arising from time-zone transitions (e.g. DST) causing the implicit other half to combine with the part being edited to make an invalid result. Returns from their dateTime() and other methods returning QDateTime (max/min) shall thus be in UTC where previously they were in local time. QDateTimeEdit continues using local time. The default can be over-ridden by setTimeSpec(), as ever. Change-Id: I44fece004c12342fe536bbe3048217d236fd97b2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
5ad13ec57d
commit
c00ee2f310
@ -2198,21 +2198,25 @@ QString QDateTimeParser::stateName(State s) const
|
||||
}
|
||||
}
|
||||
|
||||
// Only called when we want only one of date or time; use UTC to avoid bogus DST issues.
|
||||
bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
|
||||
{
|
||||
QDateTime datetime;
|
||||
if (!fromString(t, &datetime))
|
||||
QDateTime val(QDate(1900, 1, 1).startOfDay(Qt::UTC));
|
||||
const StateNode tmp = parse(t, -1, val, false);
|
||||
if (tmp.state != Acceptable || tmp.conflicts)
|
||||
return false;
|
||||
|
||||
if (time) {
|
||||
const QTime t = datetime.time();
|
||||
Q_ASSERT(!date);
|
||||
const QTime t = tmp.value.time();
|
||||
if (!t.isValid())
|
||||
return false;
|
||||
*time = t;
|
||||
}
|
||||
|
||||
if (date) {
|
||||
const QDate d = datetime.date();
|
||||
Q_ASSERT(!time);
|
||||
const QDate d = tmp.value.date();
|
||||
if (!d.isValid())
|
||||
return false;
|
||||
*date = d;
|
||||
@ -2220,7 +2224,8 @@ bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) con
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDateTimeParser::fromString(const QString &t, QDateTime* datetime) const
|
||||
// Only called when we want both date and time; default to local time.
|
||||
bool QDateTimeParser::fromString(const QString &t, QDateTime *datetime) const
|
||||
{
|
||||
QDateTime val(QDate(1900, 1, 1).startOfDay());
|
||||
const StateNode tmp = parse(t, -1, val, false);
|
||||
|
@ -223,7 +223,9 @@ QDateTimeEdit::QDateTimeEdit(QTime time, QWidget *parent)
|
||||
\internal
|
||||
*/
|
||||
QDateTimeEdit::QDateTimeEdit(const QVariant &var, QMetaType::Type parserType, QWidget *parent)
|
||||
: QAbstractSpinBox(*new QDateTimeEditPrivate, parent)
|
||||
: QAbstractSpinBox(*new QDateTimeEditPrivate(
|
||||
parserType == QMetaType::QDateTime ? Qt::LocalTime : Qt::UTC),
|
||||
parent)
|
||||
{
|
||||
Q_D(QDateTimeEdit);
|
||||
d->parserType = parserType;
|
||||
@ -1734,16 +1736,17 @@ QDateEdit::~QDateEdit()
|
||||
*/
|
||||
|
||||
|
||||
QDateTimeEditPrivate::QDateTimeEditPrivate()
|
||||
: QDateTimeParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit, QCalendar())
|
||||
QDateTimeEditPrivate::QDateTimeEditPrivate(Qt::TimeSpec timeSpec)
|
||||
: QDateTimeParser(QMetaType::QDateTime, QDateTimeParser::DateTimeEdit, QCalendar()),
|
||||
spec(timeSpec)
|
||||
{
|
||||
fixday = true;
|
||||
type = QMetaType::QDateTime;
|
||||
currentSectionIndex = FirstSectionIndex;
|
||||
|
||||
first.pos = 0;
|
||||
minimum = QDATETIMEEDIT_COMPAT_DATE_MIN.startOfDay();
|
||||
maximum = QDATETIMEEDIT_DATE_MAX.endOfDay();
|
||||
minimum = QDATETIMEEDIT_COMPAT_DATE_MIN.startOfDay(spec);
|
||||
maximum = QDATETIMEEDIT_DATE_MAX.endOfDay(spec);
|
||||
readLocaleSettings();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ class Q_AUTOTEST_EXPORT QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, p
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QDateTimeEdit)
|
||||
public:
|
||||
QDateTimeEditPrivate();
|
||||
QDateTimeEditPrivate(Qt::TimeSpec timeSpec = Qt::LocalTime);
|
||||
|
||||
void init(const QVariant &var);
|
||||
void readLocaleSettings();
|
||||
@ -153,7 +153,7 @@ public:
|
||||
bool focusOnButton = false;
|
||||
#endif
|
||||
|
||||
Qt::TimeSpec spec = Qt::LocalTime;
|
||||
Qt::TimeSpec spec;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1358,7 +1358,7 @@ void tst_QDateTimeEdit::editingRanged_data()
|
||||
<< QDate(2010, 12, 30) << QTime()
|
||||
<< QDate(2011, 1, 2) << QTime()
|
||||
<< QString::fromLatin1("01012011")
|
||||
<< QDateTime(QDate(2011, 1, 1), QTime());
|
||||
<< QDateTime(QDate(2011, 1, 1), QTime(), Qt::UTC);
|
||||
}
|
||||
|
||||
void tst_QDateTimeEdit::editingRanged()
|
||||
@ -3141,9 +3141,9 @@ void tst_QDateTimeEdit::hour12Test()
|
||||
void tst_QDateTimeEdit::yyTest()
|
||||
{
|
||||
testWidget->setDisplayFormat("dd-MMM-yy");
|
||||
testWidget->setTime(QTime(0, 0, 0));
|
||||
testWidget->setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31));
|
||||
testWidget->setDate(testWidget->minimumDate());
|
||||
testWidget->setTime(QTime(12, 0, 0)); // Mid-day to avoid DST artefacts.
|
||||
testWidget->setCurrentSection(QDateTimeEdit::YearSection);
|
||||
|
||||
QString jan = QLocale::system().monthName(1, QLocale::ShortFormat);
|
||||
|
Loading…
Reference in New Issue
Block a user