Skip to content

Commit 34f415b

Browse files
authored
Fix %S formatting for chrono durations with leading zeroes (#3814)
1 parent e17bc67 commit 34f415b

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

include/fmt/chrono.h

+12-7
Original file line numberDiff line numberDiff line change
@@ -1151,18 +1151,23 @@ void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
11511151
out = std::fill_n(out, leading_zeroes, '0');
11521152
out = format_decimal<Char>(out, n, num_digits).end;
11531153
}
1154-
} else {
1154+
} else if (precision > 0) {
11551155
*out++ = '.';
11561156
leading_zeroes = (std::min)(leading_zeroes, precision);
1157-
out = std::fill_n(out, leading_zeroes, '0');
11581157
int remaining = precision - leading_zeroes;
1159-
if (remaining != 0 && remaining < num_digits) {
1160-
n /= to_unsigned(detail::pow10(to_unsigned(num_digits - remaining)));
1161-
out = format_decimal<Char>(out, n, remaining).end;
1158+
out = std::fill_n(out, leading_zeroes, '0');
1159+
if (remaining < num_digits) {
1160+
int num_truncated_digits = num_digits - remaining;
1161+
n /= to_unsigned(detail::pow10(to_unsigned(num_truncated_digits)));
1162+
if (n) {
1163+
out = format_decimal<Char>(out, n, remaining).end;
1164+
}
11621165
return;
11631166
}
1164-
out = format_decimal<Char>(out, n, num_digits).end;
1165-
remaining -= num_digits;
1167+
if (n) {
1168+
out = format_decimal<Char>(out, n, num_digits).end;
1169+
remaining -= num_digits;
1170+
}
11661171
out = std::fill_n(out, remaining, '0');
11671172
}
11681173
}

test/chrono-test.cc

+14
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,20 @@ TEST(chrono_test, cpp20_duration_subsecond_support) {
791791
"01.234000");
792792
EXPECT_EQ(fmt::format("{:.6%S}", std::chrono::milliseconds{-1234}),
793793
"-01.234000");
794+
EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{12345}),
795+
"12.34");
796+
EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{12375}),
797+
"12.37");
798+
EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{-12375}),
799+
"-12.37");
800+
EXPECT_EQ(fmt::format("{:.0%S}", std::chrono::milliseconds{12054}),
801+
"12");
802+
EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{99999}),
803+
"39.99");
804+
EXPECT_EQ(fmt::format("{:.2%S}", std::chrono::milliseconds{1000}),
805+
"01.00");
806+
EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::milliseconds{1}),
807+
"00.001");
794808
EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::seconds{1234}), "34.000");
795809
EXPECT_EQ(fmt::format("{:.3%S}", std::chrono::hours{1234}), "00.000");
796810
EXPECT_EQ(fmt::format("{:.5%S}", dms(1.234)), "00.00123");

0 commit comments

Comments
 (0)