Add _tzset() call before mktime() on MS

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 <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
bb10
Edward Welbourne 2023-08-30 20:06:36 +02:00
parent 648f648258
commit 54c2383e81
6 changed files with 84 additions and 0 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,4 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(zonechange)

View File

@ -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
)

View File

@ -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 <QtCore/qcoreapplication.h>
#include <QtCore/qdatetime.h>
#if QT_CONFIG(timezone)
#include <QtCore/qtimezone.h>
#endif
#include <chrono>
#include <thread>
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;
}