Call _tzset() before localtime_s() in qtLocalTime()

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.

Pick-to: 6.5
Fixes: QTBUG-109974
Change-Id: Ic57753f246f14e183d2a56f131e8bed7347d2e20
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Edward Welbourne 2023-01-26 17:09:52 +01:00
parent 78c5ca4c85
commit 9d1a3582f3

View File

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