From 54c2383e81148c0195a7ddfd1d394f6c7678f4c8 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 30 Aug 2023 20:06:36 +0200 Subject: [PATCH] Add _tzset() call before mktime() on MS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a change-of-zone manual test, based on a bug-report by Felix Kälberer. This failed: debugging revealed that MS's mktime() doesn't pick up a change to system zone. Fixes: QTBUG-83881 Change-Id: I9b86398ef870627a059e269f85a0f5d9d9de284b Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim --- src/corelib/global/qtenvironmentvariables.cpp | 4 ++ tests/manual/CMakeLists.txt | 1 + tests/manual/corelib/CMakeLists.txt | 6 ++ tests/manual/corelib/time/CMakeLists.txt | 4 ++ .../corelib/time/zonechange/CMakeLists.txt | 9 +++ .../time/zonechange/tst_zonechange.cpp | 60 +++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 tests/manual/corelib/CMakeLists.txt create mode 100644 tests/manual/corelib/time/CMakeLists.txt create mode 100644 tests/manual/corelib/time/zonechange/CMakeLists.txt create mode 100644 tests/manual/corelib/time/zonechange/tst_zonechange.cpp diff --git a/src/corelib/global/qtenvironmentvariables.cpp b/src/corelib/global/qtenvironmentvariables.cpp index 47fc8f7eec..fb313d4968 100644 --- a/src/corelib/global/qtenvironmentvariables.cpp +++ b/src/corelib/global/qtenvironmentvariables.cpp @@ -353,6 +353,10 @@ void qTzSet() time_t qMkTime(struct tm *when) { const auto locker = qt_scoped_lock(environmentMutex); +#if defined(Q_OS_WIN) + // QTBUG-83881 MS's mktime() seems to need _tzset() called first. + _tzset(); +#endif return mktime(when); } diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index 035e14d4c8..788a0beb71 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -6,6 +6,7 @@ if(UIKIT) return() endif() +add_subdirectory(corelib) add_subdirectory(filetest) # diaglib is broken in dev due to missing # QtOpenGL/QGLFunctions headers diff --git a/tests/manual/corelib/CMakeLists.txt b/tests/manual/corelib/CMakeLists.txt new file mode 100644 index 0000000000..a9e85962c8 --- /dev/null +++ b/tests/manual/corelib/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(time) +# Needs conversion from qmake: +# add_subdirectory(tools) diff --git a/tests/manual/corelib/time/CMakeLists.txt b/tests/manual/corelib/time/CMakeLists.txt new file mode 100644 index 0000000000..b8e6aa2f18 --- /dev/null +++ b/tests/manual/corelib/time/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +add_subdirectory(zonechange) diff --git a/tests/manual/corelib/time/zonechange/CMakeLists.txt b/tests/manual/corelib/time/zonechange/CMakeLists.txt new file mode 100644 index 0000000000..474779849f --- /dev/null +++ b/tests/manual/corelib/time/zonechange/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_manual_test(zonechange + SOURCES + tst_zonechange.cpp + LIBRARIES + Qt::Core +) diff --git a/tests/manual/corelib/time/zonechange/tst_zonechange.cpp b/tests/manual/corelib/time/zonechange/tst_zonechange.cpp new file mode 100644 index 0000000000..1abb068c9d --- /dev/null +++ b/tests/manual/corelib/time/zonechange/tst_zonechange.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include +#if QT_CONFIG(timezone) +#include +#endif + +#include +#include + +using namespace std::chrono; + +bool distinct(const QDateTime &left, const QDateTime &right) +{ + if (left == right) + return false; + + qInfo() << " Actual:" << left << "\nExpected:" << right; + return true; +} + +// Exit status: 0 success, 1 test failed, 2 test not viable. +int main(int argc, char **argv) +{ + // Other things may need this indirectly, so make sure it exists: + QCoreApplication ignored(argc, argv); + if (!qEnvironmentVariableIsEmpty("TZ")) { + qInfo("Environment variable TZ over-rides system setting; you need to clear it."); + return 2; + } + + QDateTime date = QDateTime(QDate(2020, 2, 20), QTime(20, 20, 20)); + QDateTime copy = date; + if (distinct(date, copy)) + return 1; +#if QT_CONFIG(timezone) + const auto prior = QTimeZone::systemTimeZoneId(); +#endif + + qInfo("You have two minutes in which to change the system time-zone setting."); + std::this_thread::sleep_for(120s); +#if QT_CONFIG(timezone) + if (QTimeZone::systemTimeZoneId() == prior) { + qInfo("Too slow."); + return 2; + } +#endif + + if (distinct(copy, date)) + return 1; + QDateTime copy2 = copy.addMSecs(2); + QDateTime date2 = date.addMSecs(2); + if (distinct(copy2, date2)) + return 1; + + return 0; +}