Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions stl/inc/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -5999,6 +5999,20 @@ namespace chrono {
}
_Os << _Time.tm_mday;
return true;
case 'r':
if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) {
// put_time uses _Strftime in order to bypass reference-counting that locale uses. This function
// takes the locale information by pointer, but the pointer (from _Gettnames) returns a copy.
// _Strftime delegates to other functions but eventually (for the C locale) has the %r specifier
// rewritten. It checks for the locale by comparing pointers, which do not compare equal as we have
// a copy of the pointer instead of the original. Therefore, we replace %r for the C locale
// ourselves.
Comment on lines +6004 to +6009
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're reporting this as a UCRT bug (which I think was our conclusion in the internal chat), should this be marked as // TRANSITION, ... with a bug number? Theoretically, we won't have to special-case this forever!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not exactly a UCRT bug. They can't really tell we mean the C locale when we pass it in through _Strftime because they are fundamentally different pointers. And we are the ones trying to circumvent the ref counting of locale. Maybe we can fix time_put? People might rely on the %r behavior though...

if (_Os.getloc() == locale::classic()) {
_Os << _STD put_time(&_Time, _STATICALLY_WIDEN(_CharT, "%I:%M:%S %p"));
return true;
}
}
return false;
case 'j':
if constexpr (_Is_specialization_v<_Ty, duration>) {
_Os << _STD abs(_CHRONO duration_cast<days>(_Val).count());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,10 @@ void test_hh_mm_ss_formatter() {
empty_braces_helper(hh_mm_ss{65745s}, STR("18:15:45"));

assert(format(STR("{:%H %I %M %S %r %R %T %p}"), hh_mm_ss{13h + 14min + 15351ms})
== STR("13 01 14 15.351 13:14:15 13:14 13:14:15.351 PM"));
== STR("13 01 14 15.351 01:14:15 PM 13:14 13:14:15.351 PM"));

assert(format(STR("{:%H %I %M %S %r %R %T %p}"), hh_mm_ss{-13h - 14min - 15351ms})
== STR("-13 01 14 15.351 13:14:15 13:14 13:14:15.351 PM"));
== STR("-13 01 14 15.351 01:14:15 PM 13:14 13:14:15.351 PM"));

throw_helper(STR("{}"), hh_mm_ss{24h});
throw_helper(STR("{}"), hh_mm_ss{-24h});
Expand Down