diff --git a/CMakeLists.txt b/CMakeLists.txt index ec8154edcb4b..20a26b908033 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,7 +140,7 @@ set_verbose(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING "Installation directory for include files, a relative path that " "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute path.") -option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) +option(FMT_PEDANTIC "Enable extra warnings and expensive tests." ON) option(FMT_WERROR "Halt the compilation with an error on compiler warnings." OFF) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 09cce20feaa0..992ab4c7638b 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -1154,15 +1154,38 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) { } else { *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; + if (remaining < num_digits) { + int num_truncated_digits = num_digits - remaining; + n /= to_unsigned(detail::pow10(to_unsigned(num_truncated_digits)-1)); //002999 + const int old_num_digits = detail::count_digits(n); + int 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'); + } + else { + n -= 1; + out = format_decimal(out, n, remaining).end; + } + } + else { + out = std::fill_n(out, leading_zeroes, '0'); + out = format_decimal(out, n, remaining).end; + } return; } - out = format_decimal(out, n, num_digits).end; - remaining -= num_digits; + out = std::fill_n(out, leading_zeroes, '0'); + 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 b2d03f979578..ad45933853ea 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -791,6 +791,18 @@ 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.38"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{-12375}), + "-12.38"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{12054}), + "12.05"); + EXPECT_EQ(fmt::format("{:.1%S}", std::chrono::milliseconds{12054}), + "12.1"); + EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{99999}), + "39.99"); 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");