Use QDateTime for interfacing with QML

Summary:
QDate from/to JS Date has unexpected results, so use QDateTime to have a
timezone assigned to prevent conversions. That way the date values are
consistent.

The behaviour got changed with Qt 5.11 (see the linked bug report) which
lead to plasma showing the wrong dates in the calendar.

BUG: 394423

Test Plan:
Tested with and without this patch on Qt 5.10.1 and 5.11.0.
Now the correct date is displayed for -0004 and +0001 timezones.

Reviewers: #plasma, #frameworks, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: ngraham, Zren, sharvey, kde-frameworks-devel

Tags: #frameworks

Differential Revision: https://phabricator.kde.org/D13222
This commit is contained in:
Fabian Vogt 2018-05-30 21:27:30 +02:00
parent d7fa21a083
commit d15f0fa832
2 changed files with 29 additions and 16 deletions

View File

@ -39,9 +39,9 @@ Calendar::Calendar(QObject *parent)
// connect(m_dayHelper, SIGNAL(calendarChanged()), this, SLOT(updateData()));
}
QDate Calendar::displayedDate() const
QDateTime Calendar::displayedDate() const
{
return m_displayedDate;
return QDateTime(m_displayedDate);
}
void Calendar::setDisplayedDate(const QDate &dateTime)
@ -67,18 +67,24 @@ void Calendar::setDisplayedDate(const QDate &dateTime)
}
}
QDate Calendar::today() const
void Calendar::setDisplayedDate(const QDateTime &dateTime)
{
return m_today;
setDisplayedDate(dateTime.date());
}
void Calendar::setToday(const QDate &dateTime)
QDateTime Calendar::today() const
{
if (dateTime == m_today) {
return QDateTime(m_today);
}
void Calendar::setToday(const QDateTime &dateTime)
{
QDate date = dateTime.date();
if (date == m_today) {
return;
}
m_today = dateTime;
m_today = date;
if (m_displayedDate.isNull()) {
resetToToday();
} else {

View File

@ -32,17 +32,23 @@
class Calendar : public QObject
{
Q_OBJECT
/**
* This property is used to determine which data from which month to show, it ensures
* the day passed in the QDate is visible
*/
Q_PROPERTY(QDate displayedDate READ displayedDate WRITE setDisplayedDate NOTIFY displayedDateChanged)
/* The conversion between QDate and JS Date is broken. The specification says that a date
* is represented by the start of the UTC day, but for negative to UTC timezones this results
* in wrong dates: Jan 2 in C++ -> Jan 2 (00:00) UTC -> Jan 1 (23:00) UTC-1 in JS.
* So use QDateTime for interfacing to always carry a timezone around.
* https://bugreports.qt.io/browse/QTBUG-29328 */
/**
* This property is used to determine which data from which month to show, it ensures
* the day passed in the QDate is visible
*/
Q_PROPERTY(QDate today READ today WRITE setToday NOTIFY todayChanged)
Q_PROPERTY(QDateTime displayedDate READ displayedDate WRITE setDisplayedDate NOTIFY displayedDateChanged)
/**
* This property is used to determine which data from which month to show, it ensures
* the day passed in the QDate is visible
*/
Q_PROPERTY(QDateTime today READ today WRITE setToday NOTIFY todayChanged)
/**
* This determines which kind of data types should be contained in
@ -140,12 +146,13 @@ public:
explicit Calendar(QObject *parent = nullptr);
// Displayed date
QDate displayedDate() const;
QDateTime displayedDate() const;
void setDisplayedDate(const QDate &dateTime);
void setDisplayedDate(const QDateTime &dateTime);
// The day that represents "today"
QDate today() const;
void setToday(const QDate &dateTime);
QDateTime today() const;
void setToday(const QDateTime &dateTime);
// Types
int types() const;