https://gcc.gnu.org/g:4883c9571f5fb8fc7e873bb8a31aa164c5cfd0e0

commit r15-2424-g4883c9571f5fb8fc7e873bb8a31aa164c5cfd0e0
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Mon Jul 29 12:52:40 2024 +0100

    libstdc++: Fix formatter for low-resolution chrono::zoned_time (LWG 4124)
    
    This implements the proposed resolution of LWG 4124, so that
    low-resolution chrono::zoned_time objects can be formatted. The
    formatter for zoned_time<D, P> needs to account for get_local_time
    returning local_time<common_type_t<D, seconds>> not local_time<D>.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/chrono_io.h (__local_time_fmt_for): New alias
            template.
            (formatter<zoned_time<D, P>>): Use __local_time_fmt_for.
            * testsuite/std/time/zoned_time/io.cc: Check zoned_time<minutes>
            can be formatted.

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h            | 12 +++++++++---
 libstdc++-v3/testsuite/std/time/zoned_time/io.cc |  4 ++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index e7e7deb2cde3..d8a4a121113c 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -164,6 +164,12 @@ namespace __detail
       const string* _M_abbrev;
       const seconds* _M_offset_sec;
     };
+
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 4124. Cannot format zoned_time with resolution coarser than seconds
+  template<typename _Duration>
+    using __local_time_fmt_for
+      = __local_time_fmt<common_type_t<_Duration, seconds>>;
 }
 /// @endcond
 
@@ -2137,15 +2143,15 @@ namespace __format
 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   template<typename _Duration, typename _TimeZonePtr, typename _CharT>
     struct formatter<chrono::zoned_time<_Duration, _TimeZonePtr>, _CharT>
-    : formatter<chrono::__detail::__local_time_fmt<_Duration>, _CharT>
+    : formatter<chrono::__detail::__local_time_fmt_for<_Duration>, _CharT>
     {
       template<typename _FormatContext>
        typename _FormatContext::iterator
        format(const chrono::zoned_time<_Duration, _TimeZonePtr>& __tp,
               _FormatContext& __ctx) const
        {
-         using chrono::__detail::__local_time_fmt;
-         using _Base = formatter<__local_time_fmt<_Duration>, _CharT>;
+         using _Ltf = chrono::__detail::__local_time_fmt_for<_Duration>;
+         using _Base = formatter<_Ltf, _CharT>;
          const chrono::sys_info __info = __tp.get_info();
          const auto __lf = chrono::local_time_format(__tp.get_local_time(),
                                                      &__info.abbrev,
diff --git a/libstdc++-v3/testsuite/std/time/zoned_time/io.cc 
b/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
index ee3b9edba810..c113eea6d3fe 100644
--- a/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
+++ b/libstdc++-v3/testsuite/std/time/zoned_time/io.cc
@@ -66,6 +66,10 @@ test_format()
   ws = std::format(L"{:+^34}", zoned_time<microseconds>(zone, t));
   VERIFY( ws == L"++2022-12-19 12:26:25.708000 EST++" );
 #endif
+
+  // LWG 4124. Cannot format zoned_time with resolution coarser than seconds
+  s = std::format("{}", zoned_time<minutes>(zone, 
time_point_cast<minutes>(t)));
+  VERIFY( s == "2022-12-19 12:26:00 EST" );
 }
 
 int main()

Reply via email to