diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index bdc33e63..74d64ac9 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -401,6 +401,24 @@ inline T mod(T x, int y) { return std::fmod(x, y); } +template ::value, int>::type = 0> +inline std::chrono::duration get_milliseconds( + std::chrono::duration d) { + auto s = std::chrono::duration_cast(d); + return std::chrono::duration_cast(d - s); +} + +template < + typename Rep, typename Period, + typename std::enable_if::value, int>::type = 0> +inline std::chrono::duration get_milliseconds( + std::chrono::duration d) { + auto ms = + std::chrono::duration_cast>(d); + return std::chrono::duration(mod(ms.count(), 1000)); +} + template OutputIt static format_chrono_duration_value(OutputIt out, Rep val, int precision) { @@ -443,7 +461,7 @@ struct chrono_formatter { *out++ = '-'; } s = std::chrono::duration_cast(d); - ms = std::chrono::duration_cast(d - s); + ms = get_milliseconds(d); } Rep hour() const { return mod((s.count() / 3600), 24); } diff --git a/test/chrono-test.cc b/test/chrono-test.cc index 738686c9..fbf49b52 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -307,13 +307,17 @@ TEST(ChronoTest, InvalidColons) { } TEST(ChronoTest, SpecialDurations) { - EXPECT_EQ("40", fmt::format("{:%S}", std::chrono::duration(1e20))); + EXPECT_EQ( + "40.", + fmt::format("{:%S}", std::chrono::duration(1e20)).substr(0, 3)); EXPECT_EQ("-00:01", fmt::format("{:%M:%S}", std::chrono::duration(-1))); auto nan = std::numeric_limits::quiet_NaN(); EXPECT_EQ( "nan nan nan nan.nan nan:nan nan", fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration(nan))); + fmt::format("{:%S}", + std::chrono::duration(1.79400457e+31f)); } #endif // FMT_STATIC_THOUSANDS_SEPARATOR