From 434e30f81f8735d4c629acea485e6bb3e059e937 Mon Sep 17 00:00:00 2001 From: Mohith <122464960+MokiMeow@users.noreply.github.com> Date: Sat, 24 Oct 2026 22:58:23 +0530 Subject: [PATCH] Fix signs in floating-point duration formatting (#4981) --- include/fmt/chrono.h | 8 +++----- test/chrono-test.cc | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index c0b88b3c..62f84b6e 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1687,10 +1687,8 @@ struct duration_formatter { return true; } // must be +-inf - if (val > 0) - std::copy_n("inf", 3, out); - else - std::copy_n("-inf", 4, out); + write_sign(); + std::copy_n("inf", 3, out); return true; } @@ -1815,7 +1813,7 @@ struct duration_formatter { auto buf = memory_buffer(); write_floating_seconds(buf, std::chrono::duration(val), precision); - if (negative) *out++ = '-'; + write_sign(); if (buf.size() < 2 || buf[1] == '.') out = detail::write_padding(out, pad); out = copy(buf.begin(), buf.end(), out); diff --git a/test/chrono-test.cc b/test/chrono-test.cc index a2f419ad..f7010943 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -755,6 +755,35 @@ TEST(chrono_test, special_durations) { "01.234"); } +TEST(chrono_test, negative_floating_duration_sign) { + auto d = std::chrono::duration(-61.25); + EXPECT_EQ(fmt::format("{:%S %M}", d), "-01.250000 01"); + EXPECT_EQ(fmt::format("{:%S %S}", d), "-01.250000 01.250000"); + EXPECT_EQ(fmt::format("{:%S %Q}", d), "-01.250000 61.25"); + EXPECT_EQ(fmt::format("{:%Q %S}", d), "-61.25 01.250000"); + EXPECT_EQ(fmt::format("{:%S %Q}", -d), "01.250000 61.25"); + EXPECT_EQ(fmt::format("{:%S %Q}", std::chrono::duration(-1)), "-01 1"); + EXPECT_EQ(fmt::format("{:%S %Q}", std::chrono::duration(-1)), + "-01 1"); +} + +TEST(chrono_test, negative_infinite_duration_sign) { + auto inf = std::numeric_limits::infinity(); + auto d = std::chrono::duration(-inf); + EXPECT_EQ(fmt::format("{:%Q}", d), "-inf"); + EXPECT_EQ(fmt::format("{:%S}", d), "-inf"); + EXPECT_EQ(fmt::format("{:%H}", d), "-inf"); + EXPECT_EQ(fmt::format("{:%j}", d), "-inf"); + EXPECT_EQ(fmt::format("{:%R}", d), "-inf:inf"); + EXPECT_EQ(fmt::format("{:%T}", d), "-inf:inf:inf"); + EXPECT_EQ(fmt::format("{:%S %Q}", d), "-inf inf"); + EXPECT_EQ(fmt::format("{:>6%Q}", d), " -inf"); + EXPECT_EQ(fmt::format("{:%Q %S}", -d), "inf inf"); + EXPECT_EQ(fmt::format("{:%Q}", std::chrono::duration(-inf)), "-inf"); + EXPECT_EQ(fmt::format("{:%Q}", std::chrono::duration(-inf)), + "-inf"); +} + TEST(chrono_test, unsigned_duration) { EXPECT_EQ(fmt::format("{}", std::chrono::duration(42)), "42s"); }