From 94f3b8d5b41c990bb45ce1a77809402052746443 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Wed, 22 Oct 2025 12:39:39 -0400 Subject: [PATCH 1/4] remove deprecated fmt::localtime API --- src/gui/gui.cc | 12 +++++------- src/main/main.cc | 5 ++--- src/support/version.cc | 9 +++++++++ src/support/version.h | 1 + 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/gui/gui.cc b/src/gui/gui.cc index 9d9c22432..ae301b220 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -63,7 +63,6 @@ extern "C" { #include "core/sstate.h" #include "core/web-server.h" #include "flags.h" -#include "fmt/chrono.h" #include "gui/gui.h" #include "gui/luaimguiextra.h" #include "gui/luanvg.h" @@ -2413,16 +2412,17 @@ bool PCSX::GUI::about() { ImGui::EndDisabled(); ImGui::TextUnformatted(_("No version information.\n\nProbably built from source.")); } else { + auto timestamp = version.formatTimestamp("{:%Y-%m-%d %H:%M:%S}"); if (ImGui::Button(_("Copy to clipboard"))) { if (version.buildId.has_value()) { clip::set_text( - fmt::format("Version: {}\nBuild: {}\nChangeset: {}\nDate & time: {:%Y-%m-%d %H:%M:%S}", + fmt::format("Version: {}\nBuild: {}\nChangeset: {}\nDate & time: {}", version.version, version.buildId.value(), version.changeset, - fmt::localtime(version.timestamp))); + timestamp)); } else { - clip::set_text(fmt::format("Version: {}\nChangeset: {}\nDate & time: {:%Y-%m-%d %H:%M:%S}", + clip::set_text(fmt::format("Version: {}\nChangeset: {}\nDate & time: {}", version.version, version.changeset, - fmt::localtime(version.timestamp))); + timestamp)); } } ImGui::Text(_("Version: %s"), version.version.c_str()); @@ -2434,8 +2434,6 @@ bool PCSX::GUI::about() { if (ImGui::SmallButton(version.changeset.c_str())) { openUrl(fmt::format("https://github.com/grumpycoders/pcsx-redux/commit/{}", version.changeset)); } - std::tm tm = fmt::localtime(version.timestamp); - std::string timestamp = fmt::format("{:%Y-%m-%d %H:%M:%S}", tm); ImGui::Text(_("Date & time: %s"), timestamp.c_str()); } ImGui::EndTabItem(); diff --git a/src/main/main.cc b/src/main/main.cc index 6afb2554f..0f104a72b 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -32,7 +32,6 @@ #include "core/sstate.h" #include "core/ui.h" #include "flags.h" -#include "fmt/chrono.h" #include "gui/gui.h" #include "lua/extra.h" #include "lua/luawrapper.h" @@ -217,8 +216,8 @@ int pcsxMain(int argc, char **argv) { } fmt::print( "{{\n \"version\": \"{}\",\n \"changeset\": \"{}\",\n \"timestamp\": \"{}\",\n \"timestampDecoded\": " - "\"{:%Y-%m-%d %H:%M:%S}\"\n}}\n", - version.version, version.changeset, version.timestamp, fmt::localtime(version.timestamp)); + "\"{}\"\n}}\n", + version.version, version.changeset, version.timestamp, version.formatTimestamp("{:%Y-%m-%d %H:%M:%S}")); return 0; } diff --git a/src/support/version.cc b/src/support/version.cc index ecaca978d..670d50990 100644 --- a/src/support/version.cc +++ b/src/support/version.cc @@ -27,6 +27,9 @@ SOFTWARE. #include "support/version.h" #include +#include +#include +#include #include "json.hpp" #include "support/container-file.h" @@ -65,6 +68,12 @@ void PCSX::VersionInfo::loadFromFile(IO file) { updateStorageUrl = getString("updateStorageUrl"); } +std::string PCSX::VersionInfo::formatTimestamp(const std::string& format) const { + auto timepoint = std::chrono::system_clock::from_time_t(timestamp); + auto local = std::chrono::current_zone()->to_local(timepoint); + return fmt::format(fmt::runtime(format), floor(local)); +} + bool PCSX::Update::downloadUpdateInfo(const VersionInfo& versionInfo, std::function callback, uv_loop_t* loop) { if (versionInfo.failed() || !versionInfo.hasUpdateInfo()) return false; diff --git a/src/support/version.h b/src/support/version.h index e79dd9b87..965af0b75 100644 --- a/src/support/version.h +++ b/src/support/version.h @@ -60,6 +60,7 @@ struct VersionInfo { } return (updateMethod == "appcenter"); } + std::string formatTimestamp(const std::string& format) const; void clear() { version.clear(); buildId = std::nullopt; From 464c22f3c332fa0f34721ef1326750f9f2cf7a77 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Wed, 22 Oct 2025 16:42:48 -0400 Subject: [PATCH 2/4] add tests for formatTimestamp() --- tests/support/version.cc | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/support/version.cc diff --git a/tests/support/version.cc b/tests/support/version.cc new file mode 100644 index 000000000..9b3ce8dab --- /dev/null +++ b/tests/support/version.cc @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2025 PCSX-Redux authors * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ + +#include "support/version.h" + +#include "gtest/gtest.h" + +using namespace PCSX; + +class VersionInfoTest: public ::testing::Test { +protected: + VersionInfo vi{ + "06fdac53", + 159, + "06fdac536d1d8301fdc626fe89d1084a3ad241ad", + 1737185273, + }; +}; + +TEST_F(VersionInfoTest, TimestampFormatsDateAndTime) { + EXPECT_EQ(vi.formatTimestamp("{:%Y-%m-%d %H:%M:%S}"), "2025-01-18 02:27:53"); +} + +TEST_F(VersionInfoTest, TimestampNullFormatReturnsNullString) { + EXPECT_EQ(vi.formatTimestamp(""), ""); +} + +TEST_F(VersionInfoTest, TimestampFormatNoPlaceholderReturnsCopy) { + EXPECT_EQ(vi.formatTimestamp("abc"), "abc"); +} + +TEST_F(VersionInfoTest, TimestampFormatReturnsNonPlaceholderText) { + EXPECT_EQ(vi.formatTimestamp("123 {}"), "123 2025-01-18 02:27:53"); +} + +TEST_F(VersionInfoTest, TimestampFormatHandlesNegativeNumber) { + vi.timestamp = -1; + EXPECT_EQ(vi.formatTimestamp("{}"), "1969-12-31 18:59:59"); +} \ No newline at end of file From 5f47854bdfef61b3773e0248a626ef204e920a17 Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Thu, 23 Oct 2025 08:59:52 -0400 Subject: [PATCH 3/4] remove hardcoded timezone output --- tests/support/version.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/support/version.cc b/tests/support/version.cc index 9b3ce8dab..47bc38b8b 100644 --- a/tests/support/version.cc +++ b/tests/support/version.cc @@ -17,8 +17,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ +#include +#include #include "support/version.h" - #include "gtest/gtest.h" using namespace PCSX; @@ -31,10 +32,18 @@ class VersionInfoTest: public ::testing::Test { "06fdac536d1d8301fdc626fe89d1084a3ad241ad", 1737185273, }; + static std::string formatWithStdLocal(std::time_t ts, const char* fmt_str) { + auto tm_ptr = std::localtime(&ts); + if (!tm_ptr) { + return {}; + } + return fmt::format(fmt::runtime(fmt_str), *tm_ptr); + } }; TEST_F(VersionInfoTest, TimestampFormatsDateAndTime) { - EXPECT_EQ(vi.formatTimestamp("{:%Y-%m-%d %H:%M:%S}"), "2025-01-18 02:27:53"); + auto format = "{:%Y-%m-%d %H:%M:%S}"; + EXPECT_EQ(vi.formatTimestamp(format), formatWithStdLocal(vi.timestamp, format)); } TEST_F(VersionInfoTest, TimestampNullFormatReturnsNullString) { @@ -46,10 +55,11 @@ TEST_F(VersionInfoTest, TimestampFormatNoPlaceholderReturnsCopy) { } TEST_F(VersionInfoTest, TimestampFormatReturnsNonPlaceholderText) { - EXPECT_EQ(vi.formatTimestamp("123 {}"), "123 2025-01-18 02:27:53"); + auto format = "123 {}"; + EXPECT_EQ(vi.formatTimestamp(format), formatWithStdLocal(vi.timestamp, format)); } TEST_F(VersionInfoTest, TimestampFormatHandlesNegativeNumber) { vi.timestamp = -1; - EXPECT_EQ(vi.formatTimestamp("{}"), "1969-12-31 18:59:59"); + EXPECT_EQ(vi.formatTimestamp("{}"), formatWithStdLocal(vi.timestamp, "{}")); } \ No newline at end of file From 7b90c96de2b33c21ae1e48e5d89fa07297ff08ca Mon Sep 17 00:00:00 2001 From: Nick Fox Date: Fri, 24 Oct 2025 09:13:22 -0400 Subject: [PATCH 4/4] update to fmt 12.0.0 --- third_party/fmt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/fmt b/third_party/fmt index e69e5f977..e424e3f2e 160000 --- a/third_party/fmt +++ b/third_party/fmt @@ -1 +1 @@ -Subproject commit e69e5f977d458f2650bb346dadf2ad30c5320281 +Subproject commit e424e3f2e607da02742f73db84873b8084fc714c