Avoid narrowing duration day counts to the original representation (#5003)

* Avoid narrowing duration day counts to the original representation

* Keep duration field values in the promoted representation

---------

Co-authored-by: Aikhan Jumashukurov <117706338+aikhanj@users.noreply.github.com>
This commit is contained in:
khan 2026-11-06 18:44:43 -05:00 committed by GitHub
parent 9e7aaa3f27
commit 47fcd357ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 11 deletions

View File

@ -1703,20 +1703,16 @@ struct duration_formatter {
return true; return true;
} }
auto days() const -> Rep { return static_cast<Rep>(s.count() / 86400); } auto days() const -> rep { return s.count() / 86400; }
auto hour() const -> Rep { auto hour() const -> rep { return mod((s.count() / 3600), 24); }
return static_cast<Rep>(mod((s.count() / 3600), 24));
}
auto hour12() const -> Rep { auto hour12() const -> rep {
Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12)); auto hour = mod((s.count() / 3600), 12);
return hour < 1 ? 12 : hour; return hour < 1 ? 12 : hour;
} }
auto minute() const -> Rep { auto minute() const -> rep { return mod((s.count() / 60), 60); }
return static_cast<Rep>(mod((s.count() / 60), 60)); auto second() const -> rep { return mod(s.count(), 60); }
}
auto second() const -> Rep { return static_cast<Rep>(mod(s.count(), 60)); }
auto time() const -> std::tm { auto time() const -> std::tm {
auto time = std::tm(); auto time = std::tm();
@ -1732,7 +1728,7 @@ struct duration_formatter {
negative = false; negative = false;
} }
void write(Rep value, int width, pad_type pad = pad_type::zero) { void write(rep value, int width, pad_type pad = pad_type::zero) {
write_sign(); write_sign();
if (isnan(value)) return write_nan(); if (isnan(value)) return write_nan();
uint32_or_64_or_128_t<int> n = uint32_or_64_or_128_t<int> n =

View File

@ -546,6 +546,16 @@ TEST(chrono_test, format_specs) {
EXPECT_EQ(fmt::format("{:%q}", std::chrono::seconds(12345)), "s"); EXPECT_EQ(fmt::format("{:%q}", std::chrono::seconds(12345)), "s");
} }
TEST(chrono_test, format_days_with_signed_char_rep) {
using signed_days = std::chrono::duration<signed char, std::ratio<86400>>;
EXPECT_EQ(fmt::format("{:%j}", signed_days(-128)), "-128");
}
TEST(chrono_test, format_days_with_unsigned_char_rep) {
using two_days = std::chrono::duration<unsigned char, std::ratio<172800>>;
EXPECT_EQ(fmt::format("{:%j}", two_days(200)), "400");
}
TEST(chrono_test, invalid_specs) { TEST(chrono_test, invalid_specs) {
auto sec = std::chrono::seconds(0); auto sec = std::chrono::seconds(0);
EXPECT_THROW_MSG((void)fmt::format(runtime("{:%a}"), sec), fmt::format_error, EXPECT_THROW_MSG((void)fmt::format(runtime("{:%a}"), sec), fmt::format_error,