Tested x86_64-linux. -- >8 --
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. --- 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 e7e7deb2cde..d8a4a121113 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 ee3b9edba81..c113eea6d3f 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() -- 2.45.2