From 192291bb080bd9f1fa33a77e06b06aaf8bc8bc60 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 26 Jan 2023 17:09:52 +0100 Subject: [PATCH] Call _tzset() before localtime_s() in qtLocalTime() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Experiment reveals that we needs to, despite hints in localtime_s()'s docs that seem to indicate it shouldn't be needed. In the process document that POSIX mandates that plain localtime() behaves as if it did call tzset(), since its branch of the #if-ery is now the odd one out. Fixes: QTBUG-109974 Change-Id: Ic57753f246f14e183d2a56f131e8bed7347d2e20 Reviewed-by: Thiago Macieira Reviewed-by: MÃ¥rten Nordheim (cherry picked from commit 9d1a3582f33a0820a4f0f5b7fe84a22a8c8d967b) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/time/qlocaltime.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/time/qlocaltime.cpp b/src/corelib/time/qlocaltime.cpp index 2314c799c82..d4593e6adef 100644 --- a/src/corelib/time/qlocaltime.cpp +++ b/src/corelib/time/qlocaltime.cpp @@ -171,9 +171,10 @@ bool qtLocalTime(time_t utc, struct tm *local) // be to move this whole function there (and replace its qTzSet() with a // naked tzset(), since it'd already be mutex-protected). #if defined(Q_OS_WIN) - // The doc of localtime_s() doesn't explicitly say that it calls _tzset(), - // but does say that localtime_s() corrects for the same things _tzset() - // sets the globals for, so presumably localtime_s() behaves as if it did. + // The doc of localtime_s() says that localtime_s() corrects for the same + // things _tzset() sets the globals for, but doesn't explicitly say that it + // calls _tzset(), and QTBUG-109974 reveals the need for a _tzset() call. + qTzSet(); return !localtime_s(local, &utc); #elif QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // Use the reentrant version of localtime() where available, as it is @@ -188,8 +189,9 @@ bool qtLocalTime(time_t utc, struct tm *local) } return false; #else + // POSIX mandates that localtime() behaves as if it called tzset(). // Returns shared static data which may be overwritten at any time - // So copy the result asap + // So copy the result asap: if (tm *res = localtime(&utc)) { *local = *res; return true;