diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index f6e5e755..71606a4e 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1151,18 +1151,23 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { out = std::fill_n(out, leading_zeroes, '0'); out = format_decimal(out, n, num_digits).end; } - } else { + } else if (precision > 0) { *out++ = '.'; leading_zeroes = (std::min)(leading_zeroes, precision); - out = std::fill_n(out, leading_zeroes, '0'); int remaining = precision - leading_zeroes; - if (remaining != 0 && remaining < num_digits) { - n /= to_unsigned(detail::pow10(to_unsigned(num_digits - remaining))); - out = format_decimal(out, n, remaining).end; + out = std::fill_n(out, leading_zeroes, '0'); + if (remaining < num_digits) { + int num_truncated_digits = num_digits - remaining; + n /= to_unsigned(detail::pow10(to_unsigned(num_truncated_digits))); + if (n) { + out = format_decimal(out, n, remaining).end; + } return; } - out = format_decimal(out, n, num_digits).end; - remaining -= num_digits; + if (n) { + out = format_decimal(out, n, num_digits).end; + remaining -= num_digits; + } out = std::fill_n(out, remaining, '0'); } } diff --git a/test/chrono-test.cc b/test/chrono-test.cc index 827fa102..fa237f22 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -791,6 +791,20 @@ TEST(chrono_test, cpp20_duration_subsecond_support) { "01.234000"); EXPECT_EQ(fmt::format("{:.6%S}", std::chrono::milliseconds{-1234}), "-01.234000"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{12345}), + "12.34"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{12375}), + "12.37"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{-12375}), + "-12.37"); + EXPECT_EQ(fmt::format("{:.0%S}", std::chrono::milliseconds{12054}), + "12"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{99999}), + "39.99"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{1000}), + "01.00"); + EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::milliseconds{1}), + "00.001"); EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::seconds{1234}), "34.000"); EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::hours{1234}), "00.000"); EXPECT_EQ(fmt::format("{:.5%S}", dms(1.234)), "00.00123");