diff --git a/stl/inc/xloctime b/stl/inc/xloctime index f86e4aa0af..4517562aa5 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -888,16 +888,28 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem, const tm* _Pt, char _Specifier, char _Modifier = '\0') const { // put formatted time from _Pt to _Dest for [_Fmtfirst, _Fmtlast) - char _Fmt[5] = "!%x\0"; // '!' for nonzero count, null for modifier + const char* _Fmt_ptr = nullptr; + char _Fmt[5] = "!%x\0"; // '!' for nonzero count, null for modifier size_t _Count; size_t _Num; string _Str; - if (_Modifier == '\0') { - _Fmt[2] = _Specifier; - } else { // add both modifier and specifier - _Fmt[2] = _Modifier; - _Fmt[3] = _Specifier; + if (_Iosbase.getloc() == locale::classic()) { + if (_Specifier == 'c') { + _Fmt_ptr = "!%a %b %e %T %Y"; + } else if (_Specifier == 'r') { + _Fmt_ptr = "!%I:%M:%S %p"; + } + } + + if (!_Fmt_ptr) { + if (_Modifier == '\0') { + _Fmt[2] = _Specifier; + } else { // add both modifier and specifier + _Fmt[2] = _Modifier; + _Fmt[3] = _Specifier; + } + _Fmt_ptr = _Fmt; } int& _Errno_ref = errno; // Nonzero cost, pay it once @@ -905,7 +917,7 @@ protected: for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); - _Count = _Strftime(&_Str[0], _Str.size(), _Fmt, _Pt, _Tnames._Getptr()); + _Count = _Strftime(&_Str[0], _Str.size(), _Fmt_ptr, _Pt, _Tnames._Getptr()); if (0 < _Count) { break; } else if (_Errno_ref == EINVAL) { @@ -1034,16 +1046,28 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem, const tm* _Pt, char _Specifier, char _Modifier = '\0') const { // put formatted time from _Pt to _Dest for [_Fmtfirst, _Fmtlast) - wchar_t _Fmt[5] = L"!%x\0"; // ! for nonzero count, null for modifier + const wchar_t* _Fmt_ptr = nullptr; + wchar_t _Fmt[5] = L"!%x\0"; // ! for nonzero count, null for modifier size_t _Count; size_t _Num; wstring _Str; - if (_Modifier == '\0') { - _Fmt[2] = static_cast<_Elem>(_Specifier); // conversion rule unspecified - } else { // add both modifier and specifier - _Fmt[2] = static_cast<_Elem>(_Modifier); - _Fmt[3] = static_cast<_Elem>(_Specifier); + if (_Iosbase.getloc() == locale::classic()) { + if (_Specifier == 'c') { + _Fmt_ptr = L"!%a %b %e %T %Y"; + } else if (_Specifier == 'r') { + _Fmt_ptr = L"!%I:%M:%S %p"; + } + } + + if (!_Fmt_ptr) { + if (_Modifier == '\0') { + _Fmt[2] = static_cast<_Elem>(_Specifier); + } else { + _Fmt[2] = static_cast<_Elem>(_Modifier); + _Fmt[3] = static_cast<_Elem>(_Specifier); + } + _Fmt_ptr = _Fmt; } int& _Errno_ref = errno; // Nonzero cost, pay it once @@ -1051,7 +1075,7 @@ protected: for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); - _Count = _Wcsftime(&_Str[0], _Str.size(), _Fmt, _Pt, _Tnames._Getptr()); + _Count = _Wcsftime(&_Str[0], _Str.size(), _Fmt_ptr, _Pt, _Tnames._Getptr()); if (0 < _Count) { break; } else if (_Errno_ref == EINVAL) { @@ -1183,16 +1207,28 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem, const tm* _Pt, char _Specifier, char _Modifier = '\0') const { // put formatted time from _Pt to _Dest for [_Fmtfirst, _Fmtlast) - wchar_t _Fmt[5] = L"!%x\0"; // ! for nonzero count, null for modifier + const wchar_t* _Fmt_ptr = nullptr; + wchar_t _Fmt[5] = L"!%x\0"; // ! for nonzero count, null for modifier size_t _Count; size_t _Num; wstring _Str; - if (_Modifier == '\0') { - _Fmt[2] = static_cast<_Elem>(_Specifier); // conversion rule unspecified - } else { // add both modifier and specifier - _Fmt[2] = static_cast<_Elem>(_Modifier); - _Fmt[3] = static_cast<_Elem>(_Specifier); + if (_Iosbase.getloc() == locale::classic()) { + if (_Specifier == 'c') { + _Fmt_ptr = L"!%a %b %e %T %Y"; + } else if (_Specifier == 'r') { + _Fmt_ptr = L"!%I:%M:%S %p"; + } + } + + if (!_Fmt_ptr) { + if (_Modifier == '\0') { + _Fmt[2] = static_cast<_Elem>(_Specifier); + } else { + _Fmt[2] = static_cast<_Elem>(_Modifier); + _Fmt[3] = static_cast<_Elem>(_Specifier); + } + _Fmt_ptr = _Fmt; } int& _Errno_ref = errno; // Nonzero cost, pay it once @@ -1200,7 +1236,7 @@ protected: for (_Num = 16;; _Num *= 2) { // convert into ever larger string buffer until success _Str.append(_Num, '\0'); - _Count = _Wcsftime(&_Str[0], _Str.size(), _Fmt, _Pt, _Tnames._Getptr()); + _Count = _Wcsftime(&_Str[0], _Str.size(), _Fmt_ptr, _Pt, _Tnames._Getptr()); if (0 < _Count) { break; } else if (_Errno_ref == EINVAL) { diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index bba3bed8a1..a2be8a816b 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -566,9 +566,6 @@ std/localization/locale.categories/category.time/locale.time.get/locale.time.get std/localization/locale.categories/category.time/locale.time.get/locale.time.get.members/get_weekday.pass.cpp FAIL std/localization/locale.categories/category.time/locale.time.get/locale.time.get.members/get_weekday_wide.pass.cpp FAIL -# GH-6134 : time_put::do_put does not match strftime for the %c and %r specifiers in the "C" locale -std/localization/locale.categories/category.time/locale.time.put/locale.time.put.members/put2.pass.cpp FAIL - # GH-6135 : time_put_byname doesn't encode the output in UTF-8 even if the locale name contains ".UTF-8" std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp FAIL 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 cb1394236f..ac65ee5550 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 @@ -1012,7 +1012,7 @@ void test_local_time_format_formatter() { // Implements N4885 [time.zone.zonedtime.nonmembers]/2 for zoned_time. empty_braces_helper(ltf, STR("2021-04-19 01:02:03 Meow")); - assert(format(STR("{:%c, %x, %X}"), ltf) == STR("04/19/21 01:02:03, 04/19/21, 01:02:03")); + assert(format(STR("{:%c, %x, %X}"), ltf) == STR("Mon Apr 19 01:02:03 2021, 04/19/21, 01:02:03")); assert(format(STR("{:%D %F, %Y %C %y, %b %B %h %m, %d %e, %a %A %u %w}"), ltf) == STR("04/19/21 2021-04-19, 2021 20 21, Apr April Apr 04, 19 19, Mon Monday 1 1")); assert(format(STR("{:%H %I %M %S, %r, %R %T %p}"), ltf) == STR("01 01 02 03, 01:02:03 AM, 01:02 01:02:03 AM")); @@ -1027,7 +1027,7 @@ void test_zoned_time_formatter() { empty_braces_helper(zt, STR("2021-04-19 08:16:17 PDT"), STR("2021-04-19 08:16:17 GMT-7")); - assert(format(STR("{:%c, %x, %X}"), zt) == STR("04/19/21 08:16:17, 04/19/21, 08:16:17")); + assert(format(STR("{:%c, %x, %X}"), zt) == STR("Mon Apr 19 08:16:17 2021, 04/19/21, 08:16:17")); assert(format(STR("{:%D %F, %Y %C %y, %b %B %h %m, %d %e, %a %A %u %w}"), zt) == STR("04/19/21 2021-04-19, 2021 20 21, Apr April Apr 04, 19 19, Mon Monday 1 1")); assert(format(STR("{:%H %I %M %S, %r, %R %T %p}"), zt) == STR("08 08 16 17, 08:16:17 AM, 08:16 08:16:17 AM"));