diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 61bc9155da..1431239af2 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -138,6 +138,8 @@ add_library(common Thread.h Timer.cpp Timer.h + TimeUtil.cpp + TimeUtil.h TraversalClient.cpp TraversalClient.h TraversalProto.h diff --git a/Source/Core/Common/TimeUtil.cpp b/Source/Core/Common/TimeUtil.cpp new file mode 100644 index 0000000000..39d989fb3f --- /dev/null +++ b/Source/Core/Common/TimeUtil.cpp @@ -0,0 +1,24 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "Common/TimeUtil.h" + +#include +#include + +namespace Common +{ +std::optional Localtime(std::time_t time) +{ + std::tm local_time; +#ifdef _MSC_VER + if (localtime_s(&local_time, &time) != 0) + return std::nullopt; +#else + std::tm* result = localtime_r(&time, &local_time); + if (result != &local_time) + return std::nullopt; +#endif + return local_time; +} +} // Namespace Common diff --git a/Source/Core/Common/TimeUtil.h b/Source/Core/Common/TimeUtil.h new file mode 100644 index 0000000000..ff9ca02a12 --- /dev/null +++ b/Source/Core/Common/TimeUtil.h @@ -0,0 +1,13 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +namespace Common +{ +// Threadsafe and error-checking variant of std::localtime() +std::optional Localtime(std::time_t time); +} // Namespace Common diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index e3e9a441c2..d60747deeb 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -29,6 +29,7 @@ #include "Common/IOFile.h" #include "Common/MsgHandler.h" #include "Common/Thread.h" +#include "Common/TimeUtil.h" #include "Common/Timer.h" #include "Common/Version.h" #include "Common/WorkQueueThread.h" @@ -282,10 +283,12 @@ static std::string SystemTimeAsDoubleToString(double time) { // revert adjustments from GetSystemTimeAsDouble() to get a normal Unix timestamp again const time_t seconds = static_cast(time) + DOUBLE_TIME_OFFSET; - const tm local_time = fmt::localtime(seconds); + const auto local_time = Common::Localtime(seconds); + if (!local_time) + return ""; // fmt is locale agnostic by default, so explicitly use current locale. - return fmt::format(std::locale{""}, "{:%x %X}", local_time); + return fmt::format(std::locale{""}, "{:%x %X}", *local_time); } static std::string MakeStateFilename(int number); diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 74b3185753..42ae7ba5e6 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -161,6 +161,7 @@ + @@ -832,6 +833,7 @@ +