Tested x86_64-linux. Pushed to trunk. -- >8 --
When formatting a time point with %c we call std::vformat_to using the formatting locale's D_T_FMT string, but we weren't adding the L option to the format string. This meant we always interpreted D_T_FMT in the C locale, instead of using the formatting locale as obviously intended when %c is used. libstdc++-v3/ChangeLog: PR libstdc++/117085 * include/bits/chrono_io.h (__formatter_chrono::_M_c): Add L option to format string. * testsuite/std/time/format.cc: Move to... * testsuite/std/time/format/format.cc: ...here. * testsuite/std/time/format_localized.cc: Move to... * testsuite/std/time/format/localized.cc: ...here. * testsuite/std/time/format/pr117085.cc: New test. --- libstdc++-v3/include/bits/chrono_io.h | 14 ++++++++------ .../testsuite/std/time/{ => format}/format.cc | 0 .../localized.cc} | 0 .../testsuite/std/time/format/pr117085.cc | 19 +++++++++++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) rename libstdc++-v3/testsuite/std/time/{ => format}/format.cc (100%) rename libstdc++-v3/testsuite/std/time/{format_localized.cc => format/localized.cc} (100%) create mode 100644 libstdc++-v3/testsuite/std/time/format/pr117085.cc diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 652e88ffe3a..8c026586d4c 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -893,17 +893,19 @@ namespace __format // %c Locale's date and time representation. // %Ec Locale's alternate date and time representation. + basic_string<_CharT> __fmt; auto __t = _S_floor_seconds(__tt); locale __loc = _M_locale(__ctx); const auto& __tp = use_facet<__timepunct<_CharT>>(__loc); const _CharT* __formats[2]; __tp._M_date_time_formats(__formats); - const _CharT* __rep = __formats[__mod]; - if (!*__rep) [[unlikely]] - __rep = _GLIBCXX_WIDEN("%a %b %e %T %Y"); - basic_string<_CharT> __fmt(_S_empty_spec); - __fmt.insert(1u, 1u, _S_colon); - __fmt.insert(2u, __rep); + if (*__formats[__mod]) [[likely]] + { + __fmt = _GLIBCXX_WIDEN("{:L}"); + __fmt.insert(3u, __formats[__mod]); + } + else + __fmt = _GLIBCXX_WIDEN("{:L%a %b %e %T %Y}"); return std::vformat_to(std::move(__out), __loc, __fmt, std::make_format_args<_FormatContext>(__t)); } diff --git a/libstdc++-v3/testsuite/std/time/format.cc b/libstdc++-v3/testsuite/std/time/format/format.cc similarity index 100% rename from libstdc++-v3/testsuite/std/time/format.cc rename to libstdc++-v3/testsuite/std/time/format/format.cc diff --git a/libstdc++-v3/testsuite/std/time/format_localized.cc b/libstdc++-v3/testsuite/std/time/format/localized.cc similarity index 100% rename from libstdc++-v3/testsuite/std/time/format_localized.cc rename to libstdc++-v3/testsuite/std/time/format/localized.cc diff --git a/libstdc++-v3/testsuite/std/time/format/pr117085.cc b/libstdc++-v3/testsuite/std/time/format/pr117085.cc new file mode 100644 index 00000000000..99ef8389995 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/pr117085.cc @@ -0,0 +1,19 @@ +// { dg-do run { target c++20 } } +// { dg-require-namedlocale "fr_FR.ISO8859-1" } + +#include <chrono> +#include <locale> +#include <testsuite_hooks.h> + +void +test_c() +{ + std::locale::global(std::locale(ISO_8859(1,fr_FR))); + auto s = std::format("{:L%c}", std::chrono::sys_seconds()); + VERIFY( ! s.starts_with("Thu") ); +} + +int main() +{ + test_c(); +} -- 2.46.2