Skip to content

Commit

Permalink
Improve handling of large durations
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed May 8, 2019
1 parent f52c09f commit e9bab6d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
20 changes: 19 additions & 1 deletion include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,24 @@ inline T mod(T x, int y) {
return std::fmod(x, y);
}

template <typename Rep, typename Period,
typename std::enable_if<std::is_integral<Rep>::value, int>::type = 0>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
std::chrono::duration<Rep, Period> d) {
auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
return std::chrono::duration_cast<std::chrono::milliseconds>(d - s);
}

template <
typename Rep, typename Period,
typename std::enable_if<std::is_floating_point<Rep>::value, int>::type = 0>
inline std::chrono::duration<Rep, std::milli> get_milliseconds(
std::chrono::duration<Rep, Period> d) {
auto ms =
std::chrono::duration_cast<std::chrono::duration<Rep, std::milli>>(d);
return std::chrono::duration<Rep, std::milli>(mod(ms.count(), 1000));
}

template <typename Rep, typename OutputIt>
OutputIt static format_chrono_duration_value(OutputIt out, Rep val,
int precision) {
Expand Down Expand Up @@ -443,7 +461,7 @@ struct chrono_formatter {
*out++ = '-';
}
s = std::chrono::duration_cast<seconds>(d);
ms = std::chrono::duration_cast<milliseconds>(d - s);
ms = get_milliseconds(d);
}

Rep hour() const { return mod((s.count() / 3600), 24); }
Expand Down
6 changes: 5 additions & 1 deletion test/chrono-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,17 @@ TEST(ChronoTest, InvalidColons) {
}

TEST(ChronoTest, SpecialDurations) {
EXPECT_EQ("40", fmt::format("{:%S}", std::chrono::duration<double>(1e20)));
EXPECT_EQ(
"40.",
fmt::format("{:%S}", std::chrono::duration<double>(1e20)).substr(0, 3));
EXPECT_EQ("-00:01",
fmt::format("{:%M:%S}", std::chrono::duration<double>(-1)));
auto nan = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(
"nan nan nan nan.nan nan:nan nan",
fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration<double>(nan)));
fmt::format("{:%S}",
std::chrono::duration<float, std::atto>(1.79400457e+31f));
}

#endif // FMT_STATIC_THOUSANDS_SEPARATOR

0 comments on commit e9bab6d

Please sign in to comment.