From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 0539D3854C69; Fri, 28 Jul 2023 17:32:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0539D3854C69 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1690565572; bh=fsls4qFQfF2uyneZe0PCxdRvOWGCdnMKbazZ33PdM64=; h=From:To:Subject:Date:From; b=ll7W9YFoSnzGjNMUoBF+0dtX8Td2HHpyWeU/6N39I9KQWZ8k2mgFzBo/M+jCYYi5j AG2mjXQWqWwx9KF6lV9mJ0r4AZq+ruC7HLfMFyo8yO/eD+ndfmr1K7FkknaHVRxwo+ ToY8dZvmcmkDjQMr7b9HmGpxvvEYaWcSJ1fpIoMY= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-7631] libstdc++: Fix locale-specific duration formatting [PR110719] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-13 X-Git-Oldrev: cb01a31ab2779b0252c4945924ba2163d9150642 X-Git-Newrev: 24c352c41eb944d29b09f33a42662efad3f6f811 Message-Id: <20230728173252.0539D3854C69@sourceware.org> Date: Fri, 28 Jul 2023 17:32:52 +0000 (GMT) List-Id: https://gcc.gnu.org/g:24c352c41eb944d29b09f33a42662efad3f6f811 commit r13-7631-g24c352c41eb944d29b09f33a42662efad3f6f811 Author: Jonathan Wakely Date: Wed Jul 19 14:38:08 2023 +0100 libstdc++: Fix locale-specific duration formatting [PR110719] The r14-2640-gf4bce119f617dc commit only removed fractional seconds for time points, but it needs to be done for durations and hh_mm_ss types too. libstdc++-v3/ChangeLog: PR libstdc++/110719 * include/bits/chrono_io.h (__formatter_chrono::_S_floor_seconds): Handle duration and hh_mm_ss. * testsuite/20_util/duration/io.cc: Check locale-specific formats. * testsuite/std/time/hh_mm_ss/io.cc: Likewise. (cherry picked from commit 86b36e9f7e3839e923db2fda4962cd3faf2ea47b) Diff: --- libstdc++-v3/include/bits/chrono_io.h | 22 ++++++++++++++++------ libstdc++-v3/testsuite/20_util/duration/io.cc | 4 ++++ libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc | 24 ++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h index 43eeab42869..0c5f9f5058b 100644 --- a/libstdc++-v3/include/bits/chrono_io.h +++ b/libstdc++-v3/include/bits/chrono_io.h @@ -1144,11 +1144,11 @@ namespace __format __out = __format::__write(std::move(__out), _S_two_digits(__hms.seconds().count())); - using rep = typename decltype(__hms)::precision::rep; if constexpr (__hms.fractional_width != 0) { locale __loc = _M_locale(__ctx); auto __ss = __hms.subseconds(); + using rep = typename decltype(__ss)::rep; if constexpr (is_floating_point_v) { __out = std::format_to(__loc, std::move(__out), @@ -1546,11 +1546,21 @@ namespace __format _S_floor_seconds(const _Tp& __t) { using chrono::__detail::__local_time_fmt; - if constexpr (chrono::__is_time_point_v<_Tp>) - if constexpr (_Tp::period::den != 1) - return chrono::floor(__t); - else - return __t; + if constexpr (chrono::__is_time_point_v<_Tp> + || chrono::__is_duration_v<_Tp>) + { + if constexpr (_Tp::period::den != 1) + return chrono::floor(__t); + else + return __t; + } + else if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>) + { + if constexpr (_Tp::fractional_width != 0) + return chrono::floor(__t.to_duration()); + else + return __t; + } else if constexpr (__is_specialization_of<_Tp, __local_time_fmt>) return _S_floor_seconds(__t._M_time); else diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc index 27586b54392..ea94b062d96 100644 --- a/libstdc++-v3/testsuite/20_util/duration/io.cc +++ b/libstdc++-v3/testsuite/20_util/duration/io.cc @@ -71,6 +71,10 @@ test_format() s = std::format("{:%t} {:%t%M}", -2h, -123s); VERIFY( s == "\t \t-02" ); + // Locale-specific formats: + s = std::format(std::locale::classic(), "{:%r %OH:%OM:%OS}", 123456ms); + VERIFY( s == "12:02:03 AM 00:02:03" ); + std::string_view specs = "aAbBcCdDeFgGhHIjmMpqQrRSTuUVwWxXyYzZ"; std::string_view my_specs = "HIjMpqQrRSTX"; for (char c : specs) diff --git a/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc b/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc index 3b50f40c1f6..072234328c7 100644 --- a/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc +++ b/libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc @@ -6,7 +6,7 @@ #include void -test01() +test_ostream() { using std::ostringstream; using std::chrono::hh_mm_ss; @@ -40,7 +40,27 @@ test01() VERIFY( out.str() == "18:15:45" ); } +void +test_format() +{ + using namespace std::chrono; + + auto s = std::format("{}", hh_mm_ss{1h + 23min + 45s}); + VERIFY( s == "01:23:45" ); + + auto ws = std::format(L"{}", hh_mm_ss{1h + 23min + 45s}); + VERIFY( ws == L"01:23:45" ); + + // Locale-specific formats: + auto loc = std::locale::classic(); + s = std::format(loc, "{:%r %OH:%OM:%OS}", hh_mm_ss{123456ms}); + VERIFY( s == "12:02:03 AM 00:02:03" ); + ws = std::format(loc, L"{:%r %OH:%OM:%OS}", hh_mm_ss{123456ms}); + VERIFY( ws == L"12:02:03 AM 00:02:03" ); +} + int main() { - test01(); + test_ostream(); + test_format(); }