public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-7631] libstdc++: Fix locale-specific duration formatting [PR110719]
@ 2023-07-28 17:32 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2023-07-28 17:32 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:24c352c41eb944d29b09f33a42662efad3f6f811

commit r13-7631-g24c352c41eb944d29b09f33a42662efad3f6f811
Author: Jonathan Wakely <jwakely@redhat.com>
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<rep>)
 		{
 		  __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<chrono::seconds>(__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<chrono::seconds>(__t);
+	      else
+		return __t;
+	    }
+	  else if constexpr (__is_specialization_of<_Tp, chrono::hh_mm_ss>)
+	    {
+	      if constexpr (_Tp::fractional_width != 0)
+		return chrono::floor<chrono::seconds>(__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 <testsuite_hooks.h>
 
 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();
 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-28 17:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-28 17:32 [gcc r13-7631] libstdc++: Fix locale-specific duration formatting [PR110719] Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).