diff --git a/src/client/client.cpp b/src/client/client.cpp index 935a82653..0a1fc73d1 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1810,11 +1810,10 @@ void Client::makeScreenshot() if (!raw_image) return; - time_t t = time(NULL); - struct tm *tm = localtime(&t); + const struct tm tm = mt_localtime(); char timetstamp_c[64]; - strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", tm); + strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", &tm); std::string screenshot_dir; diff --git a/src/gettime.h b/src/gettime.h index 66efef1d7..772ff9b50 100644 --- a/src/gettime.h +++ b/src/gettime.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#include enum TimePrecision { @@ -30,13 +31,34 @@ enum TimePrecision PRECISION_NANO }; +inline struct tm mt_localtime() +{ + // initialize the time zone on first invocation + static std::once_flag tz_init; + std::call_once(tz_init, [] { +#ifdef _WIN32 + _tzset(); +#else + tzset(); +#endif + }); + + struct tm ret; + time_t t = time(NULL); + // TODO we should check if the function returns NULL, which would mean error +#ifdef _WIN32 + localtime_s(&ret, &t); +#else + localtime_r(&t, &ret); +#endif + return ret; +} + + inline std::string getTimestamp() { - time_t t = time(NULL); - // This is not really thread-safe but it won't break anything - // except its own output, so just go with it. - struct tm *tm = localtime(&t); + const struct tm tm = mt_localtime(); char cs[20]; // YYYY-MM-DD HH:MM:SS + '\0' - strftime(cs, 20, "%Y-%m-%d %H:%M:%S", tm); + strftime(cs, 20, "%Y-%m-%d %H:%M:%S", &tm); return cs; }