diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 8c5990171083..424ba08c3420 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1161,23 +1161,37 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { const int old_num_digits = detail::count_digits(n); auto roundingDigit = n % 10; n /= 10; - if (roundingDigit > 5 || (roundingDigit == 5 && n % 10 % 2 != 0)) { - n += 1; - } - if (old_num_digits == detail::count_digits(n)) { - if (leading_zeroes) { - out = std::fill_n(out, leading_zeroes-1, '0'); - *out++ = '1'; - out = std::fill_n(out, remaining, '0'); + if (n) { + if (roundingDigit > 5 || (roundingDigit == 5 && n % 10 % 2 != 0)) { + n += 1; + } + if (old_num_digits == detail::count_digits(n)) { + if (leading_zeroes) { + out = std::fill_n(out, leading_zeroes-1, '0'); + *out++ = '1'; + out = std::fill_n(out, remaining, '0'); + } + else { + n -= 1; + out = format_decimal(out, n, remaining).end; + } } else { - n -= 1; + out = std::fill_n(out, leading_zeroes, '0'); out = format_decimal(out, n, remaining).end; } } - else { - out = std::fill_n(out, leading_zeroes, '0'); - out = format_decimal(out, n, remaining).end; + else { + if (roundingDigit >= 5) { + if (leading_zeroes) { + out = std::fill_n(out, leading_zeroes-1, '0'); + *out++ = '1'; + out = std::fill_n(out, remaining, '0'); + } + } + else { + out = std::fill_n(out, leading_zeroes, '0'); + } } return; } diff --git a/test/chrono-test.cc b/test/chrono-test.cc index ad45933853ea..189ba49779ee 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -803,6 +803,10 @@ TEST(chrono_test, cpp20_duration_subsecond_support) { "12.1"); 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");