aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-12-09 16:30:03 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2022-06-10 17:19:25 +0200
commitdff02466a01caad885b6bd0759cf482342332306 (patch)
tree2bec5e778267d4040917d204048d4387e3ee13fa /tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
parent02bb4b00fa0bceb55e4cdf42e8e39a1dcc293aeb (diff)
Use qtbase's new (private) QLocalTime for Date's UTC offsets
This puts all use of system time_t functions in one place, instead of spreading it out. Its implementation improves on what was formerly done in V4 Date's offset calculations, while simplifying them and eliminating most of the #if-ery. Add four more test-cases to tst_qqmlqt::dateTimeConversion(), based on issues seen on MinGW, getting the time-zone wrong due to the failure of localtime_r(); MinGW can use localtime_s, as QLocalTime now does. Revised tst_qqmllocale::timeZoneUpdated()'s conditions. The QEXPECT_FAIL()s have stopped triggering, at least on Darwin, and the issue isn't that Date.timeZoneUpdated() wasn't working, it's that (now only on Android and Windows) we don't have a way to set the system time-zone referenced by the system functions that QLocalTime calls to get time-zone offsets. Setting the TZ environment variable only works on faithful POSIX implementations. Pick-to: 6.4 Fixes: QTBUG-85149 Fixes: QTBUG-95993 Fixes: QTBUG-102971 Change-Id: I7bc983b9fd7167e3bab3db41dbc1c6f4a78665b9 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmllocale/tst_qqmllocale.cpp')
-rw-r--r--tests/auto/qml/qqmllocale/tst_qqmllocale.cpp84
1 files changed, 37 insertions, 47 deletions
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
index 7ef0275394..d6777465f2 100644
--- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
+++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -41,6 +41,35 @@
#include <time.h>
+#undef QT_CAN_CHANGE_SYSTEM_ZONE
+/* See QTBUG-56899. We don't (yet) have a proper way to reset the system zone,
+ Testing Date.timeZoneUpdated() is only possible on systems where we have a
+ way to change the system zone in use.
+*/
+#ifdef Q_OS_ANDROID
+/* Android's time_t-related system functions don't seem to care about the TZ
+ environment variable. If we can find a way to change the zone those functions
+ use, try implementing it here.
+*/
+#elif defined(Q_OS_UNIX)
+static void setTimeZone(const QByteArray &tz)
+{
+ if (tz.isEmpty())
+ qunsetenv("TZ");
+ else
+ qputenv("TZ", tz);
+ ::tzset();
+}
+#define QT_CAN_CHANGE_SYSTEM_ZONE
+#else
+/* On Windows, adjusting the timezone (such that GetTimeZoneInformation() will
+ notice) requires additional privileges that aren't normally enabled for a
+ process. This can be achieved by calling AdjustTokenPrivileges() and then
+ SetTimeZoneInformation(), which will require linking to a different library
+ to access that API.
+*/
+#endif
+
class tst_qqmllocale : public QQmlDataTest
{
Q_OBJECT
@@ -74,7 +103,7 @@ private slots:
void dateTimeFormat();
void timeFormat_data();
void timeFormat();
-#if defined(Q_OS_UNIX) && QT_CONFIG(timezone)
+#ifdef QT_CAN_CHANGE_SYSTEM_ZONE
void timeZoneUpdated();
#endif
void formattedDataSize_data();
@@ -1370,6 +1399,7 @@ void tst_qqmllocale::localeAsCppProperty()
QCOMPARE(item->property("testLocale").toLocale().name(), QLatin1String("nb_NO"));
}
+#ifdef QT_CAN_CHANGE_SYSTEM_ZONE
class DateFormatter : public QObject
{
Q_OBJECT
@@ -1386,49 +1416,21 @@ QString DateFormatter::getLocalizedForm(const QString &isoTimestamp)
return locale.toString(input);
}
-#if defined(Q_OS_UNIX) && QT_CONFIG(timezone)
-// Currently disabled on Windows as adjusting the timezone
-// requires additional privileges that aren't normally
-// enabled for a process. This can be achieved by calling
-// AdjustTokenPrivileges() and then SetTimeZoneInformation(),
-// which will require linking to a different library to access that API.
-static void setTimeZone(const QByteArray &tz)
-{
- if (tz.isEmpty())
- qunsetenv("TZ");
- else
- qputenv("TZ", tz);
- ::tzset();
-
-// following left for future reference, see comment above
-// #if defined(Q_OS_WIN32)
-// ::_tzset();
-// #endif
-}
-
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
- setTimeZone(QByteArray("Australia/Brisbane"));
-
QScopedPointer<QObject> obj;
+
auto cleanup = qScopeGuard([&original, &obj] {
// Restore to original time zone
setTimeZone(original);
QMetaObject::invokeMethod(obj.data(), "resetTimeZone");
});
- DateFormatter formatter;
+ // Set the timezone to Brisbane time, AEST-10:00
+ setTimeZone(QByteArray("Australia/Brisbane"));
+ DateFormatter formatter;
QQmlEngine e;
e.rootContext()->setContextObject(&formatter);
@@ -1436,27 +1438,15 @@ void tst_qqmllocale::timeZoneUpdated()
QVERIFY2(!c.isError(), qPrintable(c.errorString()));
obj.reset(c.create());
QVERIFY(obj);
-
-#if (!defined(Q_OS_LINUX) && !defined(Q_OS_QNX)) || 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_LINUX) && !defined(Q_OS_QNX)) || 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 // Unix && timezone
+#endif // QT_CAN_CHANGE_SYSTEM_ZONE
QTEST_MAIN(tst_qqmllocale)