diff --git a/src/data/wallet_state.cpp b/src/data/wallet_state.cpp index dc83ee1..880ec6b 100644 --- a/src/data/wallet_state.cpp +++ b/src/data/wallet_state.cpp @@ -3,6 +3,7 @@ // Released under the GPLv3 #include "wallet_state.h" +#include "../util/text_format.h" // util::formatClockDateTime (app-wide 24h/12h clock) #include #include #include @@ -44,13 +45,7 @@ int bestSpendableAddressIndex(const std::vector& addresses) std::string TransactionInfo::getTimeString() const { if (timestamp == 0) return "Unknown"; - - std::time_t t = static_cast(timestamp); - std::tm* tm = std::localtime(&t); - - std::stringstream ss; - ss << std::put_time(tm, "%Y-%m-%d %H:%M"); - return ss.str(); + return util::formatClockDateTime(timestamp); } std::string TransactionInfo::getTypeDisplay() const @@ -77,13 +72,7 @@ std::string PeerInfo::getConnectionTime() const std::string BannedPeer::getBannedUntilString() const { if (banned_until == 0) return "Never"; - - std::time_t t = static_cast(banned_until); - std::tm* tm = std::localtime(&t); - - std::stringstream ss; - ss << std::put_time(tm, "%Y-%m-%d %H:%M"); - return ss.str(); + return util::formatClockDateTime(banned_until); } } // namespace dragonx diff --git a/src/ui/windows/block_info_dialog.cpp b/src/ui/windows/block_info_dialog.cpp index 45b2de8..a38f3b2 100644 --- a/src/ui/windows/block_info_dialog.cpp +++ b/src/ui/windows/block_info_dialog.cpp @@ -203,10 +203,7 @@ void BlockInfoDialog::render(App* app) ImGui::Text("%s", TR("block_timestamp")); ImGui::SameLine(lbl.position); if (s_block_time > 0) { - std::time_t t = static_cast(s_block_time); - char time_buf[64]; - std::strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", std::localtime(&t)); - ImGui::Text("%s", time_buf); + ImGui::Text("%s", dragonx::util::formatClockDateTime(s_block_time, /*withSeconds=*/true).c_str()); } else { ImGui::TextDisabled("%s", TR("unknown")); } diff --git a/src/ui/windows/explorer_tab.cpp b/src/ui/windows/explorer_tab.cpp index 340a827..7c45215 100644 --- a/src/ui/windows/explorer_tab.cpp +++ b/src/ui/windows/explorer_tab.cpp @@ -1127,10 +1127,8 @@ static void renderBlockDetailModal(App* app) { // Row 1: Timestamp | Confirmations drawLabelValue(dl, gx, gy, labelW, TR("block_timestamp"), "", capFont, sub1); if (s_detail_time > 0) { - std::time_t t = static_cast(s_detail_time); - char time_buf[64]; - std::strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", std::localtime(&t)); - dl->AddText(sub1, sub1->LegacySize, ImVec2(gx + labelW, gy), OnSurface(), time_buf); + const std::string tstr = dragonx::util::formatClockDateTime(s_detail_time, /*withSeconds=*/true); + dl->AddText(sub1, sub1->LegacySize, ImVec2(gx + labelW, gy), OnSurface(), tstr.c_str()); } dl->AddText(capFont, capFont->LegacySize, ImVec2(gx + halfW, gy), OnSurfaceMedium(), TR("confirmations")); snprintf(buf, sizeof(buf), "%d", s_detail_confirmations); diff --git a/src/ui/windows/transactions_tab.cpp b/src/ui/windows/transactions_tab.cpp index 51d10d3..c70b83a 100644 --- a/src/ui/windows/transactions_tab.cpp +++ b/src/ui/windows/transactions_tab.cpp @@ -64,10 +64,7 @@ struct DisplayTx { std::string DisplayTx::getTimeString() const { if (timestamp <= 0) return TR("pending"); - std::time_t t = static_cast(timestamp); - char buf[64]; - std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", std::localtime(&t)); - return buf; + return dragonx::util::formatClockDateTime(timestamp); // honors the app-wide 24h/12h clock } // Relative time string (localized long form, e.g. "5 minutes ago") diff --git a/src/util/text_format.cpp b/src/util/text_format.cpp index 4beff82..ad368e5 100644 --- a/src/util/text_format.cpp +++ b/src/util/text_format.cpp @@ -19,8 +19,38 @@ std::int64_t secondsAgo(std::int64_t timestamp) std::int64_t diff = now - timestamp; return diff < 0 ? 0 : diff; } +bool g_clock12h = false; // app-wide 12-hour clock preference (synced from settings each frame) } // namespace +void setClock12h(bool enabled) { g_clock12h = enabled; } +bool clock12h() { return g_clock12h; } + +std::string formatClockDateTime(std::int64_t timestamp, bool withSeconds) +{ + if (timestamp <= 0) return {}; + std::time_t t = static_cast(timestamp); + std::tm* tm = std::localtime(&t); // UI thread only + if (!tm) return {}; + const char* fmt = g_clock12h + ? (withSeconds ? "%Y-%m-%d %I:%M:%S %p" : "%Y-%m-%d %I:%M %p") + : (withSeconds ? "%Y-%m-%d %H:%M:%S" : "%Y-%m-%d %H:%M"); + char buf[40]; + return std::strftime(buf, sizeof(buf), fmt, tm) > 0 ? std::string(buf) : std::string(); +} + +std::string formatClockTime(std::int64_t timestamp, bool withSeconds) +{ + if (timestamp <= 0) return {}; + std::time_t t = static_cast(timestamp); + std::tm* tm = std::localtime(&t); // UI thread only + if (!tm) return {}; + const char* fmt = g_clock12h + ? (withSeconds ? "%I:%M:%S %p" : "%I:%M %p") + : (withSeconds ? "%H:%M:%S" : "%H:%M"); + char buf[24]; + return std::strftime(buf, sizeof(buf), fmt, tm) > 0 ? std::string(buf) : std::string(); +} + std::string formatTimeAgo(std::int64_t timestamp) { if (timestamp <= 0) return {}; diff --git a/src/util/text_format.h b/src/util/text_format.h index 5ab5999..f8ee7e6 100644 --- a/src/util/text_format.h +++ b/src/util/text_format.h @@ -14,6 +14,19 @@ namespace dragonx { namespace util { +// App-wide clock format (24-hour vs 12-hour). Set once per frame by the App from the global +// `time_format` setting (setClock12h); the formatters below read it so a single preference drives +// every user-facing timestamp. The Chat tab resolves its own override separately. +void setClock12h(bool enabled); +bool clock12h(); + +// Format an epoch timestamp as a local wall-clock date+time honoring the app clock setting: +// 24h -> "YYYY-MM-DD HH:MM[:SS]", 12h -> "YYYY-MM-DD hh:MM[:SS] AM/PM". Empty when ts <= 0. +std::string formatClockDateTime(std::int64_t timestamp, bool withSeconds = false); + +// Just the time-of-day portion honoring the clock setting: 24h "HH:MM[:SS]" / 12h "hh:MM[:SS] AM/PM". +std::string formatClockTime(std::int64_t timestamp, bool withSeconds = false); + // Localized relative time, e.g. "5 minutes ago" (via i18n). Empty when timestamp <= 0. std::string formatTimeAgo(std::int64_t timestamp);