From a4e5f82186d11f7a4dcd32f74d5efd3f131a627f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 19 Jun 2020 10:10:52 +0200 Subject: qv4dateobject.cpp: USE_QTZ_SYSTEM_TIMEZONE on more platforms The only platform where we may have a semi-adequate native implementation of the time/date functions is windows. On all other platforms we should use QTimeZone::systemTimeZone() if possible as that at least gives us correct results when the system time zone doesn't change at runtime. Fixes: QTBUG-84474 Change-Id: I34b01e12a751ee1c9b17735810e62e2e847f8446 Reviewed-by: Lars Knoll (cherry picked from commit 510253aa0996a89e6029d244002a08615b2fb65b) Reviewed-by: Qt Cherry-pick Bot --- src/qml/jsruntime/qv4dateobject.cpp | 21 +++++++++++++++++++-- tests/auto/qml/qqmllocale/tst_qqmllocale.cpp | 16 ++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index bebcbd7e44..4e445a73fa 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -54,11 +54,28 @@ #include -#if defined(Q_OS_LINUX) && QT_CONFIG(timezone) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(timezone) && !defined(Q_OS_WIN) /* See QTBUG-56899. Although we don't (yet) have a proper way to reset the system zone, the code below, that uses QTimeZone::systemTimeZone(), works - adequately on Linux, when the TZ environment variable is changed. + adequately on Linux. + + QTimeZone::systemTimeZone() will automatically produce an updated value on + non-android Linux systems when the TZ environment variable or the relevant + files in /etc are changed. On other platforms it won't, and the information + produced here may be incorrect after changes to the system time zone. + + We accept this defect for now because the localtime_r approach will + consistently produce incorrect results for some time zones, not only when + the system time zone changes. This is a worse problem, see also QTBUG-84474. + + On windows we have a better implementation of getLocalTZA that hopefully + updates on time zone changes. However, we currently use the worse + implementation of DaylightSavingTA (returning either an hour or 0). + + QTimeZone::systemTimeZone() on Linux is also slower than other approaches + because it has to poll the relevant files (if TZ is not set). See + QTBUG-75585 for an explanation and possible workarounds. */ #define USE_QTZ_SYSTEM_ZONE #endif diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index e3094db708..7d0c10a702 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "../../shared/util.h" @@ -1297,6 +1298,13 @@ static void setTimeZone(const QByteArray &tz) void tst_qqmllocale::timeZoneUpdated() { + // Note: This test may not reliably hit the QEXPECT_FAIL clauses below if the initial + // system time zone is equivalent to either Australia/Brisbane or Asia/Kalkota. + + // Initialize the system time zone, so that we actually _change_ something below. + QVERIFY2(QTimeZone::systemTimeZone().isValid(), + "You know, Toto, I do believe we're not in Kansas any more."); + QByteArray original(qgetenv("TZ")); // Set the timezone to Brisbane time, AEST-10:00 @@ -1318,12 +1326,20 @@ void tst_qqmllocale::timeZoneUpdated() QVERIFY2(!c.isError(), qPrintable(c.errorString())); obj.reset(c.create()); QVERIFY(obj); + +#if !defined(Q_OS_WIN) && QT_CONFIG(timezone) && (!defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) + QEXPECT_FAIL("", "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", Continue); +#endif QVERIFY(obj->property("success").toBool()); // Change to Indian time, IST-05:30 setTimeZone(QByteArray("Asia/Kolkata")); QMetaObject::invokeMethod(obj.data(), "check"); + +#if !defined(Q_OS_WIN) && QT_CONFIG(timezone) && (!defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) + QEXPECT_FAIL("", "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", Continue); +#endif QVERIFY(obj->property("success").toBool()); } #endif -- cgit v1.2.3