diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 21ddeca9..d37ed10a 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -676,6 +676,19 @@ enum class pad_type { space, }; +template +auto write_padding(OutputIt out, int width, pad_type pad) { + switch (pad) { + case pad_type::zero: + case pad_type::unspecified: + return std::fill_n(out, width, '0'); + case pad_type::space: + return std::fill_n(out, width, ' '); + case pad_type::none: + return out; + } +} + // Parses a put_time-like format string and invokes handler actions. template FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, @@ -1878,17 +1891,7 @@ struct chrono_formatter { to_unsigned(to_nonnegative_int(value, max_value())); int num_digits = detail::count_digits(n); if (width > num_digits) { - switch (pad) { - case pad_type::zero: - case pad_type::unspecified: - out = std::fill_n(out, width - num_digits, '0'); - break; - case pad_type::space: - out = std::fill_n(out, width - num_digits, ' '); - break; - case pad_type::none: - break; - } + out = detail::write_padding(out, width - num_digits, pad); } out = format_decimal(out, n, num_digits).end; } @@ -1974,7 +1977,9 @@ struct chrono_formatter { write_floating_seconds(buf, std::chrono::duration(val), precision); if (negative) *out++ = '-'; - if (buf.size() < 2 || buf[1] == '.') *out++ = '0'; + if (buf.size() < 2 || buf[1] == '.') { + out = detail::write_padding(out, 1, pad); + } out = std::copy(buf.begin(), buf.end(), out); } else { write(second(), 2, pad); diff --git a/test/chrono-test.cc b/test/chrono-test.cc index 839c1726..17e57bf5 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -949,4 +949,19 @@ TEST(chrono_test, glibc_extensions) { EXPECT_EQ(fmt::format("{:%-OI,%-OH,%-OM,%-OS}", tm), "1,1,2,3"); } + { + const auto d = std::chrono::seconds(3) + std::chrono::milliseconds(140); + EXPECT_EQ(fmt::format("{:%S}", d), "03.140"); + EXPECT_EQ(fmt::format("{:%0S}", d), "03.140"); + EXPECT_EQ(fmt::format("{:%_S}", d), " 3.140"); + EXPECT_EQ(fmt::format("{:%-S}", d), "3.140"); + } + + { + const auto d = std::chrono::duration(3.14); + EXPECT_EQ(fmt::format("{:%S}", d), "03.140000"); + EXPECT_EQ(fmt::format("{:%0S}", d), "03.140000"); + EXPECT_EQ(fmt::format("{:%_S}", d), " 3.140000"); + EXPECT_EQ(fmt::format("{:%-S}", d), "3.140000"); + } }