Fix subsecond formatting for pre-epoch local_time (#4975) (#4976)

This commit is contained in:
Kartikey Negi 2026-10-18 19:15:15 +05:30 committed by GitHub
parent 18164eaf8b
commit 6ba294f5a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 0 deletions

View File

@ -2245,6 +2245,15 @@ struct formatter<local_time<Duration>, Char>
}
auto subsecs =
detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);
if (subsecs.count() < 0) {
auto second = detail::duration_cast<Duration>(std::chrono::seconds(1));
if (t.tm_sec != 0) {
--t.tm_sec;
} else {
t = gmtime(seconds_since_epoch.count() - 1);
}
subsecs += second;
}
return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);
}
};

View File

@ -332,6 +332,14 @@ TEST(chrono_test, local_time) {
fmt::format_error, "no timezone");
EXPECT_THROW_MSG((void)fmt::format(fmt::runtime("{:%Z}"), time),
fmt::format_error, "no timezone");
auto epoch = fmt::local_time<std::chrono::milliseconds>();
auto d = std::chrono::milliseconds(250);
EXPECT_EQ(fmt::format("{:%S}", epoch - d), "59.750");
auto pre_epoch = fmt::local_time<std::chrono::milliseconds>(
std::chrono::milliseconds(-14398877));
EXPECT_EQ(fmt::format("{:%S}", pre_epoch), "01.123");
}
template <typename T, FMT_ENABLE_IF(fmt::detail::has_tm_gmtoff<T>::value)>