Fix %S formatting for chrono durations with leading zeroes (#3814)

This commit is contained in:
js324
2024-02-07 12:47:32 -05:00
committed by GitHub
parent e17bc67547
commit 34f415b56e
2 changed files with 26 additions and 7 deletions

View File

@ -1151,18 +1151,23 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
out = std::fill_n(out, leading_zeroes, '0'); out = std::fill_n(out, leading_zeroes, '0');
out = format_decimal<Char>(out, n, num_digits).end; out = format_decimal<Char>(out, n, num_digits).end;
} }
} else { } else if (precision > 0) {
*out++ = '.'; *out++ = '.';
leading_zeroes = (std::min)(leading_zeroes, precision); leading_zeroes = (std::min)(leading_zeroes, precision);
out = std::fill_n(out, leading_zeroes, '0');
int remaining = precision - leading_zeroes; int remaining = precision - leading_zeroes;
if (remaining != 0 && remaining < num_digits) { out = std::fill_n(out, leading_zeroes, '0');
n /= to_unsigned(detail::pow10(to_unsigned(num_digits - remaining))); if (remaining < num_digits) {
out = format_decimal<Char>(out, n, remaining).end; int num_truncated_digits = num_digits - remaining;
n /= to_unsigned(detail::pow10(to_unsigned(num_truncated_digits)));
if (n) {
out = format_decimal<Char>(out, n, remaining).end;
}
return; return;
} }
out = format_decimal<Char>(out, n, num_digits).end; if (n) {
remaining -= num_digits; out = format_decimal<Char>(out, n, num_digits).end;
remaining -= num_digits;
}
out = std::fill_n(out, remaining, '0'); out = std::fill_n(out, remaining, '0');
} }
} }

View File

@ -791,6 +791,20 @@ TEST(chrono_test, cpp20_duration_subsecond_support) {
"01.234000"); "01.234000");
EXPECT_EQ(fmt::format("{:.6%S}", std::chrono::milliseconds{-1234}), EXPECT_EQ(fmt::format("{:.6%S}", std::chrono::milliseconds{-1234}),
"-01.234000"); "-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::seconds{1234}), "34.000");
EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::hours{1234}), "00.000"); EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::hours{1234}), "00.000");
EXPECT_EQ(fmt::format("{:.5%S}", dms(1.234)), "00.00123"); EXPECT_EQ(fmt::format("{:.5%S}", dms(1.234)), "00.00123");