diff --git a/stl/inc/chrono b/stl/inc/chrono index 5f3d3b9aaa..ef8d383e0a 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -6014,6 +6014,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. + 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(_Val).count()); diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp index 520fe496af..0305df6786 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_formatting/test.cpp @@ -595,10 +595,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});