On Mon, 26 Oct 2026 at 12:11, Jonathan Wakely <[email protected]> wrote:
>
> On Mon, 26 Oct 2026 at 11:58, Tomasz Kamiński <[email protected]> wrote:
> >
> > Attaching below suggestions as incremental diff from yours patch.
> > ---
> > libstdc++-v3/include/std/chrono | 21 ++++++--
> > .../time/zoned_time/custom_freestanding.cc | 48 +++++++++++++++++++
> > 2 files changed, 65 insertions(+), 4 deletions(-)
> > create mode 100644
> > libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
> >
> > diff --git a/libstdc++-v3/include/std/chrono
> > b/libstdc++-v3/include/std/chrono
> > index 10e2830b66c..a74a28e73f9 100644
> > --- a/libstdc++-v3/include/std/chrono
> > +++ b/libstdc++-v3/include/std/chrono
> > @@ -3160,6 +3160,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > };
> >
> > #if __cpp_lib_chrono >= 201803L // C++ >= 20 && HOSTED && USE_CXX11_ABI
> > + using zoned_seconds = zoned_time<seconds>;
> >
> > zoned_time() -> zoned_time<seconds>;
> >
> > @@ -3174,6 +3175,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > const time_zone*,
> > remove_cvref_t<_TimeZonePtrOrName>>;
> > /// @endcond
> > +#else
> > + /// @cond undocumented
> > + template<typename _TimeZonePtr>
> > + struct __time_zone_representation_impl
> > + {
> > + static_assert(!std::is_convertible_v<_TimeZonePtr, string_view>,
> > + "std::time_zone is not supported in freedstanding mode,"
> > + " use custom time_zone representation");
> > + using type = remove_cvref_t<_TimeZonePtr>;
> > + };
> > +
> > + template<typename _TimeZonePtrOrName>
> > + using __time_zone_representation
> > + = typename __time_zone_representation_impl<_TimeZonePtrOrName>::type;
> > + /// @endcond
> > +#endif // __cpp_lib_chrono >= 201803L
> >
> > template<typename _TimeZonePtrOrName>
> > zoned_time(_TimeZonePtrOrName&&)
> > @@ -3197,10 +3214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > -> zoned_time<common_type_t<_Duration, seconds>,
> > __time_zone_representation<_TimeZonePtrOrName>>;
> >
> > - using zoned_seconds = zoned_time<seconds>;
> > -
> > -#endif // __cpp_lib_chrono >= 201803L
> > -
> > template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename
> > _TZPtr2>
> > [[nodiscard]]
> > inline bool
> > diff --git
> > a/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
> > b/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
> > new file mode 100644
> > index 00000000000..ae7d1970206
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/std/time/zoned_time/custom_freestanding.cc
> > @@ -0,0 +1,48 @@
> > +// { dg-do run { target c++20 } }
> > +
> > +#include <chrono>
> > +#include <type_traits>
> > +#include <testsuite_hooks.h>
> > +
> > +struct zone_offset
> > +{
> > + std::chrono::seconds offset;
> > +
> > + template<typename Dur>
> > + std::chrono::local_time<std::common_type_t<Dur, std::chrono::seconds>>
> > + to_local(const std::chrono::sys_time<Dur>& tp) const noexcept
> > + { return std::chrono::local_time<std::common_type_t<Dur,
> > std::chrono::seconds>>(tp.time_since_epoch() + offset); }
> > +
> > + template<typename Dur>
> > + std::chrono::sys_time<std::common_type_t<Dur, std::chrono::seconds>>
> > + to_sys(const std::chrono::local_time<Dur>& tp) const noexcept
> > + { return std::chrono::sys_time<std::common_type_t<Dur,
> > std::chrono::seconds>>(tp.time_since_epoch() - offset); }
> > +
> > + // Allows zone_offset to be stored directly in zoned_time
> > + const zone_offset* operator->() const noexcept
> > + { return this; }
> > +};
> > +
> > +void
> > +test_custom_tzptr()
> > +{
> > + using namespace std::chrono;
> > +
> > + static_assert( !std::is_default_constructible_v<zoned_time<seconds,
> > zone_offset>> );
> > + static_assert( !std::is_constructible_v<zoned_time<seconds,
> > zone_offset>, std::string_view> );
> > +
> > + zoned_time z1(zone_offset{1h}, sys_days(2012y/December/12) + 12h);
>
> This fails the static_assert in __time_zone_representation_struct,
> because zone_offset is not convertible to string_view.
Ah the assertion needs to be !is_convertible
>
>
>
> > + static_assert( std::is_same_v<decltype(z1), zoned_time<seconds,
> > zone_offset>> );
> > + VERIFY( z1.get_sys_time() == sys_days(2012y/December/12) + 12h );
> > + VERIFY( z1.get_local_time() == local_days(2012y/December/12) + 13h );
> > +
> > + zoned_time z2(zone_offset{1h}, local_days(2012y/December/12) + 12h);
> > + static_assert( std::is_same_v<decltype(z2), zoned_time<seconds,
> > zone_offset>> );
> > + VERIFY( z1.get_sys_time() == sys_days(2012y/December/12) + 11h );
> > + VERIFY( z1.get_local_time() == local_days(2012y/December/12) + 12h );
> > +}
> > +
> > +int main()
> > +{
> > + test_custom_tzptr();
> > +}
> > --
> > 2.56.0
> >