aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2023-07-19 14:38:08 +0100
committerJonathan Wakely <jwakely@redhat.com>2023-07-28 18:30:56 +0100
commit24c352c41eb944d29b09f33a42662efad3f6f811 (patch)
tree4c239881b4a00d7ab60089f38fcd6b02b376c0a3 /libstdc++-v3
parentcb01a31ab2779b0252c4945924ba2163d9150642 (diff)
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)
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/include/bits/chrono_io.h22
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/io.cc4
-rw-r--r--libstdc++-v3/testsuite/std/time/hh_mm_ss/io.cc24
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();
}