diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-10-11 09:40:38 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-10-11 15:48:17 +0100 |
commit | 4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b (patch) | |
tree | 33b421643faf22d7d7ef29ef7dec1eed4c05b955 | |
parent | c10b442ee48484c1d15db2c91deac501b7e0b14e (diff) | |
download | gcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.zip gcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.tar.gz gcc-4ad697bb7f1aad252e1398c6f13eed3fa6d0ca5b.tar.bz2 |
libstdc++: Fix localized %c formatting for <chrono> [PR117085]
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.
-rw-r--r-- | libstdc++-v3/include/bits/chrono_io.h | 14 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format/format.cc (renamed from libstdc++-v3/testsuite/std/time/format.cc) | 0 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format/localized.cc (renamed from libstdc++-v3/testsuite/std/time/format_localized.cc) | 0 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format/pr117085.cc | 19 |
4 files changed, 27 insertions, 6 deletions
diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 652e88f..8c02658 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 index d6e3583..d6e3583 100644 --- a/libstdc++-v3/testsuite/std/time/format.cc +++ b/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 index 393d0d2..393d0d2 100644 --- a/libstdc++-v3/testsuite/std/time/format_localized.cc +++ b/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 0000000..99ef838 --- /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(); +} |