From 92d2c541e3523f6e0a7beb04bc63fcc0430b643e Mon Sep 17 00:00:00 2001 From: Nathan Chandrasekar <322284620+vera-rubin@users.noreply.github.com> Date: Sat, 31 Oct 2026 11:27:00 -0400 Subject: [PATCH] Fix 12-hour formatting of floating-point durations (#4988) --- include/fmt/chrono.h | 2 +- test/chrono-test.cc | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 56a9e0f4..afcb9086 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1682,7 +1682,7 @@ struct duration_formatter { auto hour12() const -> Rep { Rep hour = static_cast(mod((s.count() / 3600), 12)); - return hour <= 0 ? 12 : hour; + return hour < 1 ? 12 : hour; } auto minute() const -> Rep { diff --git a/test/chrono-test.cc b/test/chrono-test.cc index a3cb594f..974e612d 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -545,6 +545,15 @@ TEST(chrono_test, format_specs) { EXPECT_EQ(fmt::format("{:%q}", std::chrono::seconds(12345)), "s"); } +TEST(chrono_test, format_12_hour_fp) { + using seconds = std::chrono::duration; + EXPECT_EQ(fmt::format("{:%I:%M:%S %p}", seconds(1)), "12:00:01 AM"); + EXPECT_EQ(fmt::format("{:%I:%M:%S %p}", seconds(43201)), "12:00:01 PM"); + EXPECT_EQ(fmt::format("{:%I}", seconds(3599)), "12"); + EXPECT_EQ(fmt::format("{:%I}", seconds(3600)), "01"); + EXPECT_EQ(fmt::format("{:%I}", seconds(86401)), "12"); +} + TEST(chrono_test, invalid_specs) { auto sec = std::chrono::seconds(0); EXPECT_THROW_MSG((void)fmt::format(runtime("{:%a}"), sec), fmt::format_error,