diff options
author | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-06-13 13:28:30 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-06-13 17:20:30 +0200 |
commit | 33e3139f5df09a13b8b13844d8e21ef3bb4d618e (patch) | |
tree | 5d2296482d3a64c6efd58322ee44a6b1af148bff /libstdc++-v3/testsuite/std | |
parent | 5e8168a659ecc63804984d20365b4df401d9675b (diff) | |
download | gcc-33e3139f5df09a13b8b13844d8e21ef3bb4d618e.zip gcc-33e3139f5df09a13b8b13844d8e21ef3bb4d618e.tar.gz gcc-33e3139f5df09a13b8b13844d8e21ef3bb4d618e.tar.bz2 |
libstdc++: Format %r, %x and %X using locale's time_put facet [PR120648]
Similarly to issue reported for %c in PR117214, the format string for locale
specific time (%r, %X) and date (%x) representations may contain specifiers
not accepted by chrono-spec, leading to exception being thrown. This
happened for following conversion specifier and locale combinations:
* %r, %X for aa_DJ.UTF-8, ar_SA.UTF-8
* %x for ca_AD.UTF-8, my_MM.UTF-8
This fix follows approach from r15-8490-gc24a1d5, and uses time_put to emit
localized date format. The existing _M_c is reworked to handle all locale
dependent conversion specifies, by accepting them as argument. It is also
renamed to _M_c_r_x_X.
PR libstdc++/120648
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__formatter_chrono::_M_format_to):
Handle %c, %r, %x and %X by passing them to _M_c_r_x_X.
(__formatter_chrono::_M_c_r_x_X): Reworked from _M_c.
(__formatter_chrono::_M_c): Renamed into above.
(__formatter_chrono::_M_r, __formatter_chrono::_M_x)
(__formatter_chrono::_M_X): Removed.
* testsuite/std/time/format/pr117214.cc: New tests for %r, %x,
%X with date, time and durations.
Diffstat (limited to 'libstdc++-v3/testsuite/std')
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format/pr117214.cc | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/libstdc++-v3/testsuite/std/time/format/pr117214.cc b/libstdc++-v3/testsuite/std/time/format/pr117214.cc index 87c703d..79109c3 100644 --- a/libstdc++-v3/testsuite/std/time/format/pr117214.cc +++ b/libstdc++-v3/testsuite/std/time/format/pr117214.cc @@ -7,10 +7,14 @@ #include <chrono> #include <locale> +#include <span> #include <testsuite_hooks.h> + +template<typename ChronoType> void -test_c() +test_locale_formats(const ChronoType& t, + std::span<const char* const> test_specifiers) { const char *test_locales[] = { "aa_DJ.UTF-8", @@ -19,15 +23,44 @@ test_c() "az_IR.UTF-8", "my_MM.UTF-8", }; - std::chrono::sys_seconds t{std::chrono::seconds{1}}; + auto format_args = std::make_format_args(t); for (auto locale_name : test_locales) { - auto s = std::format(std::locale(locale_name), "{:L%c}", t); - VERIFY( !s.empty() ); + std::locale loc(locale_name); + for (auto specifier : test_specifiers) + { + auto s = std::vformat(loc, specifier, format_args); + VERIFY( !s.empty() ); + } } } +void +test_locale_formats() +{ + using namespace std::chrono; + + const char* test_specifiers[] = { + "{:L%x}", "{:L%Ex}", + "{:L%c}", "{:L%Ec}", + "{:L%X}", "{:L%EX}", + "{:L%r}", + }; + auto date_time_specifiers = std::span(test_specifiers); + auto date_specifiers = date_time_specifiers.subspan(0, 2); + auto time_specifiers = date_time_specifiers.subspan(4); + + auto ymd = 2020y/November/12d; + test_locale_formats(ymd, date_specifiers); + + auto tod = 25h + 10min + 12s; + test_locale_formats(tod, time_specifiers); + + auto tp = sys_days(ymd) + tod; + test_locale_formats(tp, date_time_specifiers); +} + #include <stdlib.h> #include <time.h> @@ -93,7 +126,7 @@ test_c_local() int main() { - test_c(); + test_locale_formats(); test_c_zoned(); test_c_local(); } |