From cf7537453b29acd67ccf91142baf6fc59a2088a9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 19 May 2024 01:33:20 +0200 Subject: [PATCH] QgsDateTimeEdit: convert datetime to UTC when format string includes a Z Fixes #57262 --- src/gui/editorwidgets/qgsdatetimeedit.cpp | 3 +++ src/gui/editorwidgets/qgsdatetimeeditconfig.cpp | 12 ++++++++++++ src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp | 6 ++++++ tests/src/python/test_qgsdatetimeedit.py | 12 ++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/gui/editorwidgets/qgsdatetimeedit.cpp b/src/gui/editorwidgets/qgsdatetimeedit.cpp index 20f58ca51e2d..3cdbb4200f73 100644 --- a/src/gui/editorwidgets/qgsdatetimeedit.cpp +++ b/src/gui/editorwidgets/qgsdatetimeedit.cpp @@ -346,6 +346,9 @@ void QgsDateTimeEdit::setDateTime( const QDateTime &dateTime ) { // changed emits a signal, so don't allow it to be emitted from setDateTime mBlockChangedSignal++; + // We need to set the time spec of the set datetime to the widget, otherwise + // the dateTime() getter would loose edit, and return local time. + QDateTimeEdit::setTimeSpec( dateTime.timeSpec() ); QDateTimeEdit::setDateTime( dateTime ); mBlockChangedSignal--; changed( dateTime ); diff --git a/src/gui/editorwidgets/qgsdatetimeeditconfig.cpp b/src/gui/editorwidgets/qgsdatetimeeditconfig.cpp index 0a2da04e2731..db4f566b748c 100644 --- a/src/gui/editorwidgets/qgsdatetimeeditconfig.cpp +++ b/src/gui/editorwidgets/qgsdatetimeeditconfig.cpp @@ -411,6 +411,18 @@ QgsDateTimeEditConfig::QgsDateTimeEditConfig( QgsVectorLayer *vl, int fieldIdx, void QgsDateTimeEditConfig::updateDemoWidget() { + // Use a UTC datetime if the format string includes a Z + if ( mDisplayFormatEdit->text().indexOf( "Z" ) > 0 ) + { + mDemoDateTimeEdit->setTimeSpec( Qt::UTC ); + mDemoDateTimeEdit->setDateTime( QDateTime::currentDateTimeUtc() ); + } + else + { + mDemoDateTimeEdit->setTimeSpec( Qt::LocalTime ); + mDemoDateTimeEdit->setDateTime( QDateTime::currentDateTime() ); + } + mDemoDateTimeEdit->setDisplayFormat( mDisplayFormatEdit->text() ); mDemoDateTimeEdit->setCalendarPopup( mCalendarPopupCheckBox->isChecked() ); } diff --git a/src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp b/src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp index 817b9d11756e..3e3f641e1f91 100644 --- a/src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp +++ b/src/gui/editorwidgets/qgsdatetimeeditwrapper.cpp @@ -271,6 +271,12 @@ void QgsDateTimeEditWrapper::updateValues( const QVariant &value, const QVariant if ( mQgsDateTimeEdit ) { + // Convert to UTC if the format string includes a Z + if ( mQgsDateTimeEdit->displayFormat().indexOf( "Z" ) > 0 ) + { + dateTime = dateTime.toUTC(); + } + mQgsDateTimeEdit->setDateTime( dateTime ); } else diff --git a/tests/src/python/test_qgsdatetimeedit.py b/tests/src/python/test_qgsdatetimeedit.py index b3ff7892d0b7..3d22ec221cd7 100644 --- a/tests/src/python/test_qgsdatetimeedit.py +++ b/tests/src/python/test_qgsdatetimeedit.py @@ -17,6 +17,7 @@ start_app() DATE = QDateTime.fromString('2018-01-01 01:02:03', Qt.DateFormat.ISODate) +DATE_Z = QDateTime.fromString('2018-01-01 01:02:03Z', Qt.DateFormat.ISODate) class TestQgsDateTimeEdit(QgisTestCase): @@ -32,6 +33,17 @@ def testSettersGetters(self): w.setDateTime(QDateTime()) self.assertEqual(w.dateTime(), DATE) + def testSettersGetters_DATE_Z(self): + """ test widget handling with Z time spec """ + w = QgsDateTimeEdit() + w.setAllowNull(False) + + w.setDateTime(DATE_Z) + self.assertEqual(w.dateTime(), DATE_Z) + # date should remain when setting an invalid date + w.setDateTime(QDateTime()) + self.assertEqual(w.dateTime(), DATE_Z) + def testNullValueHandling(self): """ test widget handling of null values """ w = QgsDateTimeEdit()