From 8e42eef4950feb5d2b76574a9cd2591dfaae2449 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 10 Feb 2024 17:31:01 -0800 Subject: [PATCH] Don't error on min time_point --- include/fmt/chrono.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 71606a4ef5c3..ac31baaaf2e1 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -2155,27 +2155,26 @@ struct formatter, template auto format(std::chrono::time_point val, FormatContext& ctx) const -> decltype(ctx.out()) { + std::tm tm = gmtime(val); using period = typename Duration::period; if (detail::const_check( - period::num != 1 || period::den != 1 || - std::is_floating_point::value)) { - const auto epoch = val.time_since_epoch(); - auto subsecs = detail::fmt_duration_cast( - epoch - detail::fmt_duration_cast(epoch)); - - if (subsecs.count() < 0) { - auto second = - detail::fmt_duration_cast(std::chrono::seconds(1)); - if (epoch.count() < ((Duration::min)() + second).count()) - FMT_THROW(format_error("duration is too small")); - subsecs += second; - val -= second; - } - - return formatter::do_format(gmtime(val), ctx, &subsecs); + period::num == 1 && period::den == 1 && + !std::is_floating_point::value)) { + return formatter::format(tm, ctx); } - - return formatter::format(gmtime(val), ctx); + Duration epoch = val.time_since_epoch(); + Duration subsecs = detail::fmt_duration_cast( + epoch - detail::fmt_duration_cast(epoch)); + if (subsecs.count() < 0) { + auto second = + detail::fmt_duration_cast(std::chrono::seconds(1)); + if (tm.tm_sec != 0) + --tm.tm_sec; + else + tm = gmtime(val - second); + subsecs += detail::fmt_duration_cast(std::chrono::seconds(1)); + } + return formatter::do_format(tm, ctx, &subsecs); } };