Home | History | Annotate | Line # | Download | only in std
      1 // <chrono> -*- C++ -*-
      2 
      3 // Copyright (C) 2008-2024 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file include/chrono
     26  *  This is a Standard C++ Library header.
     27  *  @ingroup chrono
     28  */
     29 
     30 #ifndef _GLIBCXX_CHRONO
     31 #define _GLIBCXX_CHRONO 1
     32 
     33 #pragma GCC system_header
     34 
     35 #include <bits/requires_hosted.h> // for <ctime> and clocks
     36 
     37 #if __cplusplus < 201103L
     38 # include <bits/c++0x_warning.h>
     39 #else
     40 
     41 #include <bits/chrono.h>
     42 
     43 #if __cplusplus >= 202002L
     44 # include <bit>
     45 # include <sstream>
     46 # include <string>
     47 # include <vector>
     48 # include <bits/stl_algo.h> // upper_bound
     49 # include <bits/shared_ptr.h>
     50 # include <bits/unique_ptr.h>
     51 #endif
     52 
     53 #define __glibcxx_want_chrono
     54 #define __glibcxx_want_chrono_udls
     55 #include <bits/version.h>
     56 
     57 namespace std _GLIBCXX_VISIBILITY(default)
     58 {
     59 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     60 
     61   /**
     62    * @defgroup chrono Time
     63    * @ingroup utilities
     64    *
     65    * Classes and functions for time.
     66    *
     67    * @since C++11
     68    */
     69 
     70   /** @namespace std::chrono
     71    *  @brief ISO C++ 2011 namespace for date and time utilities
     72    *  @ingroup chrono
     73    */
     74   namespace chrono
     75   {
     76 #if __cplusplus >= 202002L
     77     /// @addtogroup chrono
     78     /// @{
     79     struct local_t { };
     80     template<typename _Duration>
     81       using local_time = time_point<local_t, _Duration>;
     82     using local_seconds = local_time<seconds>;
     83     using local_days = local_time<days>;
     84 
     85     class utc_clock;
     86     class tai_clock;
     87     class gps_clock;
     88 
     89     template<typename _Duration>
     90       using utc_time = time_point<utc_clock, _Duration>;
     91     using utc_seconds = utc_time<seconds>;
     92 
     93     template<typename _Duration>
     94       using tai_time = time_point<tai_clock, _Duration>;
     95     using tai_seconds = tai_time<seconds>;
     96 
     97     template<typename _Duration>
     98       using gps_time = time_point<gps_clock, _Duration>;
     99     using gps_seconds = gps_time<seconds>;
    100 
    101     template<> struct is_clock<utc_clock> : true_type { };
    102     template<> struct is_clock<tai_clock> : true_type { };
    103     template<> struct is_clock<gps_clock> : true_type { };
    104 
    105     template<> inline constexpr bool is_clock_v<utc_clock> = true;
    106     template<> inline constexpr bool is_clock_v<tai_clock> = true;
    107     template<> inline constexpr bool is_clock_v<gps_clock> = true;
    108 
    109     struct leap_second_info
    110     {
    111       bool is_leap_second;
    112       seconds elapsed;
    113     };
    114 
    115     template<typename _Duration>
    116       leap_second_info
    117       get_leap_second_info(const utc_time<_Duration>& __ut);
    118 
    119     /** A clock that measures Universal Coordinated Time (UTC).
    120      *
    121      * The epoch is 1970-01-01 00:00:00.
    122      *
    123      * @since C++20
    124      */
    125     class utc_clock
    126     {
    127     public:
    128       using rep                       = system_clock::rep;
    129       using period                    = system_clock::period;
    130       using duration                  = chrono::duration<rep, period>;
    131       using time_point                = chrono::time_point<utc_clock>;
    132       static constexpr bool is_steady = false;
    133 
    134       [[nodiscard]]
    135       static time_point
    136       now()
    137       { return from_sys(system_clock::now()); }
    138 
    139       template<typename _Duration>
    140 	[[nodiscard]]
    141 	static sys_time<common_type_t<_Duration, seconds>>
    142 	to_sys(const utc_time<_Duration>& __t)
    143 	{
    144 	  using _CDur = common_type_t<_Duration, seconds>;
    145 	  const auto __li = chrono::get_leap_second_info(__t);
    146 	  sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
    147 	  if (__li.is_leap_second)
    148 	    __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
    149 	  return __s;
    150 	}
    151 
    152       template<typename _Duration>
    153 	[[nodiscard]]
    154 	static utc_time<common_type_t<_Duration, seconds>>
    155 	from_sys(const sys_time<_Duration>& __t);
    156     };
    157 
    158     /** A clock that measures International Atomic Time.
    159      *
    160      * The epoch is 1958-01-01 00:00:00.
    161      *
    162      * @since C++20
    163      */
    164     class tai_clock
    165     {
    166     public:
    167       using rep                       = system_clock::rep;
    168       using period                    = system_clock::period;
    169       using duration                  = chrono::duration<rep, period>;
    170       using time_point                = chrono::time_point<tai_clock>;
    171       static constexpr bool is_steady = false; // XXX true for CLOCK_TAI?
    172 
    173       // TODO move into lib, use CLOCK_TAI on linux, add extension point.
    174       [[nodiscard]]
    175       static time_point
    176       now()
    177       { return from_utc(utc_clock::now()); }
    178 
    179       template<typename _Duration>
    180 	[[nodiscard]]
    181 	static utc_time<common_type_t<_Duration, seconds>>
    182 	to_utc(const tai_time<_Duration>& __t)
    183 	{
    184 	  using _CDur = common_type_t<_Duration, seconds>;
    185 	  return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
    186 	}
    187 
    188       template<typename _Duration>
    189 	[[nodiscard]]
    190 	static tai_time<common_type_t<_Duration, seconds>>
    191 	from_utc(const utc_time<_Duration>& __t)
    192 	{
    193 	  using _CDur = common_type_t<_Duration, seconds>;
    194 	  return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
    195 	}
    196     };
    197 
    198     /** A clock that measures GPS time.
    199      *
    200      * The epoch is 1980-01-06 00:00:00.
    201      *
    202      * @since C++20
    203      */
    204     class gps_clock
    205     {
    206     public:
    207       using rep                       = system_clock::rep;
    208       using period                    = system_clock::period;
    209       using duration                  = chrono::duration<rep, period>;
    210       using time_point                = chrono::time_point<gps_clock>;
    211       static constexpr bool is_steady = false; // XXX
    212 
    213       // TODO move into lib, add extension point.
    214       [[nodiscard]]
    215       static time_point
    216       now()
    217       { return from_utc(utc_clock::now()); }
    218 
    219       template<typename _Duration>
    220 	[[nodiscard]]
    221 	static utc_time<common_type_t<_Duration, seconds>>
    222 	to_utc(const gps_time<_Duration>& __t)
    223 	{
    224 	  using _CDur = common_type_t<_Duration, seconds>;
    225 	  return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
    226 	}
    227 
    228       template<typename _Duration>
    229 	[[nodiscard]]
    230 	static gps_time<common_type_t<_Duration, seconds>>
    231 	from_utc(const utc_time<_Duration>& __t)
    232 	{
    233 	  using _CDur = common_type_t<_Duration, seconds>;
    234 	  return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
    235 	}
    236     };
    237 
    238 
    239     template<typename _DestClock, typename _SourceClock>
    240       struct clock_time_conversion
    241       { };
    242 
    243     // Identity conversions
    244 
    245     template<typename _Clock>
    246       struct clock_time_conversion<_Clock, _Clock>
    247       {
    248 	template<typename _Duration>
    249 	  time_point<_Clock, _Duration>
    250 	  operator()(const time_point<_Clock, _Duration>& __t) const
    251 	  { return __t; }
    252       };
    253 
    254     template<>
    255       struct clock_time_conversion<system_clock, system_clock>
    256       {
    257 	template<typename _Duration>
    258 	  sys_time<_Duration>
    259 	  operator()(const sys_time<_Duration>& __t) const
    260 	  { return __t; }
    261       };
    262 
    263     template<>
    264       struct clock_time_conversion<utc_clock, utc_clock>
    265       {
    266 	template<typename _Duration>
    267 	  utc_time<_Duration>
    268 	  operator()(const utc_time<_Duration>& __t) const
    269 	  { return __t; }
    270       };
    271 
    272     // Conversions between system_clock and utc_clock
    273 
    274     template<>
    275       struct clock_time_conversion<utc_clock, system_clock>
    276       {
    277 	template<typename _Duration>
    278 	  utc_time<common_type_t<_Duration, seconds>>
    279 	  operator()(const sys_time<_Duration>& __t) const
    280 	  { return utc_clock::from_sys(__t); }
    281       };
    282 
    283     template<>
    284       struct clock_time_conversion<system_clock, utc_clock>
    285       {
    286 	template<typename _Duration>
    287 	  sys_time<common_type_t<_Duration, seconds>>
    288 	  operator()(const utc_time<_Duration>& __t) const
    289 	  { return utc_clock::to_sys(__t); }
    290       };
    291 
    292     template<typename _Tp, typename _Clock>
    293       inline constexpr bool __is_time_point_for_v = false;
    294 
    295     template<typename _Clock, typename _Duration>
    296       inline constexpr bool
    297        __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
    298 
    299     // Conversions between system_clock and other clocks
    300 
    301     template<typename _SourceClock>
    302       struct clock_time_conversion<system_clock, _SourceClock>
    303       {
    304 	template<typename _Duration, typename _Src = _SourceClock>
    305 	  auto
    306 	  operator()(const time_point<_SourceClock, _Duration>& __t) const
    307 	  -> decltype(_Src::to_sys(__t))
    308 	  {
    309 	    using _Ret = decltype(_SourceClock::to_sys(__t));
    310 	    static_assert(__is_time_point_for_v<_Ret, system_clock>);
    311 	    return _SourceClock::to_sys(__t);
    312 	  }
    313       };
    314 
    315     template<typename _DestClock>
    316       struct clock_time_conversion<_DestClock, system_clock>
    317       {
    318 	template<typename _Duration, typename _Dest = _DestClock>
    319 	  auto
    320 	  operator()(const sys_time<_Duration>& __t) const
    321 	  -> decltype(_Dest::from_sys(__t))
    322 	  {
    323 	    using _Ret = decltype(_DestClock::from_sys(__t));
    324 	    static_assert(__is_time_point_for_v<_Ret, _DestClock>);
    325 	    return _DestClock::from_sys(__t);
    326 	  }
    327       };
    328 
    329     // Conversions between utc_clock and other clocks
    330 
    331     template<typename _SourceClock>
    332       struct clock_time_conversion<utc_clock, _SourceClock>
    333       {
    334 	template<typename _Duration, typename _Src = _SourceClock>
    335 	  auto
    336 	  operator()(const time_point<_SourceClock, _Duration>& __t) const
    337 	  -> decltype(_Src::to_utc(__t))
    338 	  {
    339 	    using _Ret = decltype(_SourceClock::to_utc(__t));
    340 	    static_assert(__is_time_point_for_v<_Ret, utc_clock>);
    341 	    return _SourceClock::to_utc(__t);
    342 	  }
    343       };
    344 
    345     template<typename _DestClock>
    346       struct clock_time_conversion<_DestClock, utc_clock>
    347       {
    348 	template<typename _Duration, typename _Dest = _DestClock>
    349 	  auto
    350 	  operator()(const utc_time<_Duration>& __t) const
    351 	  -> decltype(_Dest::from_utc(__t))
    352 	  {
    353 	    using _Ret = decltype(_DestClock::from_utc(__t));
    354 	    static_assert(__is_time_point_for_v<_Ret, _DestClock>);
    355 	    return _DestClock::from_utc(__t);
    356 	  }
    357       };
    358 
    359     /// @cond undocumented
    360     namespace __detail
    361     {
    362       template<typename _DestClock, typename _SourceClock, typename _Duration>
    363        concept __clock_convs
    364 	  = requires (const time_point<_SourceClock, _Duration>& __t) {
    365 	    clock_time_conversion<_DestClock, _SourceClock>{}(__t);
    366 	  };
    367 
    368       template<typename _DestClock, typename _SourceClock, typename _Duration>
    369        concept __clock_convs_sys
    370 	  = requires (const time_point<_SourceClock, _Duration>& __t) {
    371 	    clock_time_conversion<_DestClock, system_clock>{}(
    372 	      clock_time_conversion<system_clock, _SourceClock>{}(__t));
    373 	  };
    374 
    375       template<typename _DestClock, typename _SourceClock, typename _Duration>
    376        concept __clock_convs_utc
    377 	  = requires (const time_point<_SourceClock, _Duration>& __t) {
    378 	    clock_time_conversion<_DestClock, utc_clock>{}(
    379 	      clock_time_conversion<utc_clock, _SourceClock>{}(__t));
    380 	  };
    381 
    382       template<typename _DestClock, typename _SourceClock, typename _Duration>
    383 	concept __clock_convs_sys_utc
    384 	  = requires (const time_point<_SourceClock, _Duration>& __t) {
    385 	    clock_time_conversion<_DestClock, utc_clock>{}(
    386 	      clock_time_conversion<utc_clock, system_clock>{}(
    387 		clock_time_conversion<system_clock, _SourceClock>{}(__t)));
    388 	  };
    389 
    390       template<typename _DestClock, typename _SourceClock, typename _Duration>
    391        concept __clock_convs_utc_sys
    392 	  = requires (const time_point<_SourceClock, _Duration>& __t) {
    393 	    clock_time_conversion<_DestClock, system_clock>{}(
    394 	      clock_time_conversion<system_clock, utc_clock>{}(
    395 		clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
    396 	  };
    397 
    398     } // namespace __detail
    399     /// @endcond
    400 
    401     /// Convert a time point to a different clock.
    402     template<typename _DestClock, typename _SourceClock, typename _Duration>
    403       [[nodiscard]]
    404       inline auto
    405       clock_cast(const time_point<_SourceClock, _Duration>& __t)
    406       requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
    407 	|| __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
    408 	|| __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
    409 	|| __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
    410 	|| __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
    411       {
    412        constexpr bool __direct
    413 	 = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
    414        if constexpr (__direct)
    415 	 {
    416 	   return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
    417 	 }
    418        else
    419 	 {
    420 	   constexpr bool __convert_via_sys_clock
    421 	     = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
    422 	   constexpr bool __convert_via_utc_clock
    423 	     = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
    424 	   if constexpr (__convert_via_sys_clock)
    425 	     {
    426 	       static_assert(!__convert_via_utc_clock,
    427 		 "clock_cast requires a unique best conversion, but "
    428 		 "conversion is possible via system_clock and also via"
    429 		 "utc_clock");
    430 	       return clock_time_conversion<_DestClock, system_clock>{}(
    431 			clock_time_conversion<system_clock, _SourceClock>{}(__t));
    432 	     }
    433 	   else if constexpr (__convert_via_utc_clock)
    434 	     {
    435 	       return clock_time_conversion<_DestClock, utc_clock>{}(
    436 			clock_time_conversion<utc_clock, _SourceClock>{}(__t));
    437 	     }
    438 	   else
    439 	     {
    440 	       constexpr bool __convert_via_sys_and_utc_clocks
    441 		 = __detail::__clock_convs_sys_utc<_DestClock,
    442 						   _SourceClock,
    443 						   _Duration>;
    444 
    445 	       if constexpr (__convert_via_sys_and_utc_clocks)
    446 		 {
    447 		   constexpr bool __convert_via_utc_and_sys_clocks
    448 		     = __detail::__clock_convs_utc_sys<_DestClock,
    449 						       _SourceClock,
    450 						       _Duration>;
    451 		   static_assert(!__convert_via_utc_and_sys_clocks,
    452 		     "clock_cast requires a unique best conversion, but "
    453 		     "conversion is possible via system_clock followed by "
    454 		     "utc_clock, and also via utc_clock followed by "
    455 		     "system_clock");
    456 		   return clock_time_conversion<_DestClock, utc_clock>{}(
    457 			    clock_time_conversion<utc_clock, system_clock>{}(
    458 			      clock_time_conversion<system_clock, _SourceClock>{}(__t)));
    459 		 }
    460 	       else
    461 		 {
    462 		   return clock_time_conversion<_DestClock, system_clock>{}(
    463 			    clock_time_conversion<system_clock, utc_clock>{}(
    464 			      clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
    465 		 }
    466 	     }
    467 	 }
    468       }
    469 
    470     // CALENDRICAL TYPES
    471 
    472     // CLASS DECLARATIONS
    473     class day;
    474     class month;
    475     class year;
    476     class weekday;
    477     class weekday_indexed;
    478     class weekday_last;
    479     class month_day;
    480     class month_day_last;
    481     class month_weekday;
    482     class month_weekday_last;
    483     class year_month;
    484     class year_month_day;
    485     class year_month_day_last;
    486     class year_month_weekday;
    487     class year_month_weekday_last;
    488 
    489     struct last_spec
    490     {
    491       explicit last_spec() = default;
    492 
    493       friend constexpr month_day_last
    494       operator/(int __m, last_spec) noexcept;
    495 
    496       friend constexpr month_day_last
    497       operator/(last_spec, int __m) noexcept;
    498     };
    499 
    500     inline constexpr last_spec last{};
    501 
    502     namespace __detail
    503     {
    504       // Helper to __add_modulo and __sub_modulo.
    505       template <unsigned __d, typename _Tp>
    506       consteval auto
    507       __modulo_offset()
    508       {
    509 	using _Up = make_unsigned_t<_Tp>;
    510 	auto constexpr __a = _Up(-1) - _Up(255 + __d - 2);
    511 	auto constexpr __b = _Up(__d * (__a / __d) - 1);
    512 	// Notice: b <= a - 1 <= _Up(-1) - (255 + d - 1) and b % d = d - 1.
    513 	return _Up(-1) - __b; // >= 255 + d - 1
    514       }
    515 
    516       // Compute the remainder of the Euclidean division of __x + __y divided by
    517       // __d without overflowing.  Typically, __x <= 255 + d - 1 is sum of
    518       // weekday/month with a shift in [0, d - 1] and __y is a duration count.
    519       template <unsigned __d, typename _Tp>
    520       constexpr unsigned
    521       __add_modulo(unsigned __x, _Tp __y)
    522       {
    523 	using _Up = make_unsigned_t<_Tp>;
    524 	// For __y >= 0, _Up(__y) has the same mathematical value as __y and
    525 	// this function simply returns (__x + _Up(__y)) % d.  Typically, this
    526 	// doesn't overflow since the range of _Up contains many more positive
    527 	// values than _Tp's.  For __y < 0, _Up(__y) has a mathematical value in
    528 	// the upper-half range of _Up so that adding a positive value to it
    529 	// might overflow.  Moreover, most likely, _Up(__y) != __y mod d.  To
    530 	// fix both issues we subtract from _Up(__y) an __offset >=
    531 	// 255 + d - 1 to make room for the addition to __x and shift the modulo
    532 	// to the correct value.
    533 	auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
    534 	return (__x + _Up(__y) - __offset) % __d;
    535       }
    536 
    537       // Similar to __add_modulo but for __x - __y.
    538       template <unsigned __d, typename _Tp>
    539       constexpr unsigned
    540       __sub_modulo(unsigned __x, _Tp __y)
    541       {
    542 	using _Up = make_unsigned_t<_Tp>;
    543 	auto const __offset = __y <= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
    544 	return (__x - _Up(__y) - __offset) % __d;
    545       }
    546 
    547       inline constexpr unsigned __days_per_month[12]
    548 	= { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    549     }
    550 
    551     // DAY
    552 
    553     class day
    554     {
    555     private:
    556       unsigned char _M_d;
    557 
    558     public:
    559       day() = default;
    560 
    561       explicit constexpr
    562       day(unsigned __d) noexcept
    563       : _M_d(__d)
    564       { }
    565 
    566       constexpr day&
    567       operator++() noexcept
    568       {
    569 	++_M_d;
    570 	return *this;
    571       }
    572 
    573       constexpr day
    574       operator++(int) noexcept
    575       {
    576 	auto __ret = *this;
    577 	++(*this);
    578 	return __ret;
    579       }
    580 
    581       constexpr day&
    582       operator--() noexcept
    583       {
    584 	--_M_d;
    585 	return *this;
    586       }
    587 
    588       constexpr day
    589       operator--(int) noexcept
    590       {
    591 	auto __ret = *this;
    592 	--(*this);
    593 	return __ret;
    594       }
    595 
    596       constexpr day&
    597       operator+=(const days& __d) noexcept
    598       {
    599 	*this = *this + __d;
    600 	return *this;
    601       }
    602 
    603       constexpr day&
    604       operator-=(const days& __d) noexcept
    605       {
    606 	*this = *this - __d;
    607 	return *this;
    608       }
    609 
    610       constexpr explicit
    611       operator unsigned() const noexcept
    612       { return _M_d; }
    613 
    614       constexpr bool
    615       ok() const noexcept
    616       { return 1 <= _M_d && _M_d <= 31; }
    617 
    618       friend constexpr bool
    619       operator==(const day& __x, const day& __y) noexcept
    620       { return unsigned{__x} == unsigned{__y}; }
    621 
    622       friend constexpr strong_ordering
    623       operator<=>(const day& __x, const day& __y) noexcept
    624       { return unsigned{__x} <=> unsigned{__y}; }
    625 
    626       friend constexpr day
    627       operator+(const day& __x, const days& __y) noexcept
    628       { return day(unsigned{__x} + __y.count()); }
    629 
    630       friend constexpr day
    631       operator+(const days& __x, const day& __y) noexcept
    632       { return __y + __x; }
    633 
    634       friend constexpr day
    635       operator-(const day& __x, const days& __y) noexcept
    636       { return __x + -__y; }
    637 
    638       friend constexpr days
    639       operator-(const day& __x, const day& __y) noexcept
    640       { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
    641 
    642       friend constexpr month_day
    643       operator/(const month& __m, const day& __d) noexcept;
    644 
    645       friend constexpr month_day
    646       operator/(int __m, const day& __d) noexcept;
    647 
    648       friend constexpr month_day
    649       operator/(const day& __d, const month& __m) noexcept;
    650 
    651       friend constexpr month_day
    652       operator/(const day& __d, int __m) noexcept;
    653 
    654       friend constexpr year_month_day
    655       operator/(const year_month& __ym, const day& __d) noexcept;
    656     };
    657 
    658     // MONTH
    659 
    660     class month
    661     {
    662     private:
    663       unsigned char _M_m;
    664 
    665     public:
    666       month() = default;
    667 
    668       explicit constexpr
    669       month(unsigned __m) noexcept
    670       : _M_m(__m)
    671       { }
    672 
    673       constexpr month&
    674       operator++() noexcept
    675       {
    676 	*this += months{1};
    677 	return *this;
    678       }
    679 
    680       constexpr month
    681       operator++(int) noexcept
    682       {
    683 	auto __ret = *this;
    684 	++(*this);
    685 	return __ret;
    686       }
    687 
    688       constexpr month&
    689       operator--() noexcept
    690       {
    691 	*this -= months{1};
    692 	return *this;
    693       }
    694 
    695       constexpr month
    696       operator--(int) noexcept
    697       {
    698 	auto __ret = *this;
    699 	--(*this);
    700 	return __ret;
    701       }
    702 
    703       constexpr month&
    704       operator+=(const months& __m) noexcept
    705       {
    706 	*this = *this + __m;
    707 	return *this;
    708       }
    709 
    710       constexpr month&
    711       operator-=(const months& __m) noexcept
    712       {
    713 	*this = *this - __m;
    714 	return *this;
    715       }
    716 
    717       explicit constexpr
    718       operator unsigned() const noexcept
    719       { return _M_m; }
    720 
    721       constexpr bool
    722       ok() const noexcept
    723       { return 1 <= _M_m && _M_m <= 12; }
    724 
    725       friend constexpr bool
    726       operator==(const month& __x, const month& __y) noexcept
    727       { return unsigned{__x} == unsigned{__y}; }
    728 
    729       friend constexpr strong_ordering
    730       operator<=>(const month& __x, const month& __y) noexcept
    731       { return unsigned{__x} <=> unsigned{__y}; }
    732 
    733       friend constexpr month
    734       operator+(const month& __x, const months& __y) noexcept
    735       {
    736 	// modulo(x + (y - 1), 12) = modulo(x + (y - 1) + 12, 12)
    737 	//                         = modulo((x + 11) + y    , 12)
    738 	return month{1 + __detail::__add_modulo<12>(
    739 	  unsigned{__x} + 11, __y.count())};
    740       }
    741 
    742       friend constexpr month
    743       operator+(const months& __x,  const month& __y) noexcept
    744       { return __y + __x; }
    745 
    746       friend constexpr month
    747       operator-(const month& __x, const months& __y) noexcept
    748       {
    749 	// modulo(x + (-y - 1), 12) = modulo(x + (-y - 1) + 12, 12)
    750 	//                          = modulo((x + 11) - y     , 12)
    751 	return month{1 + __detail::__sub_modulo<12>(
    752 	  unsigned{__x} + 11, __y.count())};
    753       }
    754 
    755       friend constexpr months
    756       operator-(const month& __x,  const month& __y) noexcept
    757       {
    758 	const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
    759 	return months{__dm < 0 ? 12 + __dm : __dm};
    760       }
    761 
    762       friend constexpr year_month
    763       operator/(const year& __y, const month& __m) noexcept;
    764 
    765       friend constexpr month_day
    766       operator/(const month& __m, int __d) noexcept;
    767 
    768       friend constexpr month_day_last
    769       operator/(const month& __m, last_spec) noexcept;
    770 
    771       friend constexpr month_day_last
    772       operator/(last_spec, const month& __m) noexcept;
    773 
    774       friend constexpr month_weekday
    775       operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
    776 
    777       friend constexpr month_weekday
    778       operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
    779 
    780       friend constexpr month_weekday_last
    781       operator/(const month& __m, const weekday_last& __wdl) noexcept;
    782 
    783       friend constexpr month_weekday_last
    784       operator/(const weekday_last& __wdl, const month& __m) noexcept;
    785     };
    786 
    787     inline constexpr month January{1};
    788     inline constexpr month February{2};
    789     inline constexpr month March{3};
    790     inline constexpr month April{4};
    791     inline constexpr month May{5};
    792     inline constexpr month June{6};
    793     inline constexpr month July{7};
    794     inline constexpr month August{8};
    795     inline constexpr month September{9};
    796     inline constexpr month October{10};
    797     inline constexpr month November{11};
    798     inline constexpr month December{12};
    799 
    800     // YEAR
    801 
    802     class year
    803     {
    804     private:
    805       short _M_y;
    806 
    807     public:
    808       year() = default;
    809 
    810       explicit constexpr
    811       year(int __y) noexcept
    812       : _M_y{static_cast<short>(__y)}
    813       { }
    814 
    815       static constexpr year
    816       min() noexcept
    817       { return year{-32767}; }
    818 
    819       static constexpr year
    820       max() noexcept
    821       { return year{32767}; }
    822 
    823       constexpr year&
    824       operator++() noexcept
    825       {
    826 	++_M_y;
    827 	return *this;
    828       }
    829 
    830       constexpr year
    831       operator++(int) noexcept
    832       {
    833 	auto __ret = *this;
    834 	++(*this);
    835 	return __ret;
    836       }
    837 
    838       constexpr year&
    839       operator--() noexcept
    840       {
    841 	--_M_y;
    842 	return *this;
    843       }
    844 
    845       constexpr year
    846       operator--(int) noexcept
    847       {
    848 	auto __ret = *this;
    849 	--(*this);
    850 	return __ret;
    851       }
    852 
    853       constexpr year&
    854       operator+=(const years& __y) noexcept
    855       {
    856 	*this = *this + __y;
    857 	return *this;
    858       }
    859 
    860       constexpr year&
    861       operator-=(const years& __y) noexcept
    862       {
    863 	*this = *this - __y;
    864 	return *this;
    865       }
    866 
    867       constexpr year
    868       operator+() const noexcept
    869       { return *this; }
    870 
    871       constexpr year
    872       operator-() const noexcept
    873       { return year{-_M_y}; }
    874 
    875       constexpr bool
    876       is_leap() const noexcept
    877       {
    878 	// Testing divisibility by 100 first gives better performance [1], i.e.,
    879 	//     return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
    880 	// Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
    881 	// to _M_y % 16 == 0, so we can simplify it to
    882 	//     return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #1
    883 	// Similarly, we can replace 100 with 25 (which is good since
    884 	// _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
    885 	// [2]):
    886 	//     return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0.  // #2
    887 	// Indeed, first assume _M_y % 4 != 0.  Then _M_y % 16 != 0 and hence,
    888 	// _M_y % 4 == 0 and _M_y % 16 == 0 are both false.  Therefore, #2
    889 	// returns false as it should (regardless of _M_y % 25.) Now assume
    890 	// _M_y % 4 == 0.  In this case, _M_y % 25 == 0 if, and only if,
    891 	// _M_y % 100 == 0, that is, #1 and #2 are equivalent.  Finally, #2 is
    892 	// equivalent to
    893 	//     return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
    894 
    895 	// References:
    896 	// [1] https://github.com/cassioneri/calendar
    897 	// [2] https://godbolt.org/z/55G8rn77e
    898 	// [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
    899 
    900 	return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
    901       }
    902 
    903       explicit constexpr
    904       operator int() const noexcept
    905       { return _M_y; }
    906 
    907       constexpr bool
    908       ok() const noexcept
    909       { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
    910 
    911       friend constexpr bool
    912       operator==(const year& __x, const year& __y) noexcept
    913       { return int{__x} == int{__y}; }
    914 
    915       friend constexpr strong_ordering
    916       operator<=>(const year& __x, const year& __y) noexcept
    917       { return int{__x} <=> int{__y}; }
    918 
    919       friend constexpr year
    920       operator+(const year& __x, const years& __y) noexcept
    921       { return year{int{__x} + static_cast<int>(__y.count())}; }
    922 
    923       friend constexpr year
    924       operator+(const years& __x, const year& __y) noexcept
    925       { return __y + __x; }
    926 
    927       friend constexpr year
    928       operator-(const year& __x, const years& __y) noexcept
    929       { return __x + -__y; }
    930 
    931       friend constexpr years
    932       operator-(const year& __x, const year& __y) noexcept
    933       { return years{int{__x} - int{__y}}; }
    934 
    935       friend constexpr year_month
    936       operator/(const year& __y, int __m) noexcept;
    937 
    938       friend constexpr year_month_day
    939       operator/(const year& __y, const month_day& __md) noexcept;
    940 
    941       friend constexpr year_month_day
    942       operator/(const month_day& __md, const year& __y) noexcept;
    943 
    944       friend constexpr year_month_day_last
    945       operator/(const year& __y, const month_day_last& __mdl) noexcept;
    946 
    947       friend constexpr year_month_day_last
    948       operator/(const month_day_last& __mdl, const year& __y) noexcept;
    949 
    950       friend constexpr year_month_weekday
    951       operator/(const year& __y, const month_weekday& __mwd) noexcept;
    952 
    953       friend constexpr year_month_weekday
    954       operator/(const month_weekday& __mwd, const year& __y) noexcept;
    955 
    956       friend constexpr year_month_weekday_last
    957       operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
    958 
    959       friend constexpr year_month_weekday_last
    960       operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
    961     };
    962 
    963     // WEEKDAY
    964 
    965     class weekday
    966     {
    967     private:
    968       unsigned char _M_wd;
    969 
    970       static constexpr weekday
    971       _S_from_days(const days& __d)
    972       {
    973 	return weekday{__detail::__add_modulo<7>(4, __d.count())};
    974       }
    975 
    976     public:
    977       weekday() = default;
    978 
    979       explicit constexpr
    980       weekday(unsigned __wd) noexcept
    981       : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
    982       { }
    983 
    984       constexpr
    985       weekday(const sys_days& __dp) noexcept
    986       : weekday{_S_from_days(__dp.time_since_epoch())}
    987       { }
    988 
    989       explicit constexpr
    990       weekday(const local_days& __dp) noexcept
    991       : weekday{sys_days{__dp.time_since_epoch()}}
    992       { }
    993 
    994       constexpr weekday&
    995       operator++() noexcept
    996       {
    997 	*this += days{1};
    998 	return *this;
    999       }
   1000 
   1001       constexpr weekday
   1002       operator++(int) noexcept
   1003       {
   1004 	auto __ret = *this;
   1005 	++(*this);
   1006 	return __ret;
   1007       }
   1008 
   1009       constexpr weekday&
   1010       operator--() noexcept
   1011       {
   1012 	*this -= days{1};
   1013 	return *this;
   1014       }
   1015 
   1016       constexpr weekday
   1017       operator--(int) noexcept
   1018       {
   1019 	auto __ret = *this;
   1020 	--(*this);
   1021 	return __ret;
   1022       }
   1023 
   1024       constexpr weekday&
   1025       operator+=(const days& __d) noexcept
   1026       {
   1027 	*this = *this + __d;
   1028 	return *this;
   1029       }
   1030 
   1031       constexpr weekday&
   1032       operator-=(const days& __d) noexcept
   1033       {
   1034 	*this = *this - __d;
   1035 	return *this;
   1036       }
   1037 
   1038       constexpr unsigned
   1039       c_encoding() const noexcept
   1040       { return _M_wd; }
   1041 
   1042       constexpr unsigned
   1043       iso_encoding() const noexcept
   1044       { return _M_wd == 0u ? 7u : _M_wd; }
   1045 
   1046       constexpr bool
   1047       ok() const noexcept
   1048       { return _M_wd <= 6; }
   1049 
   1050       constexpr weekday_indexed
   1051       operator[](unsigned __index) const noexcept;
   1052 
   1053       constexpr weekday_last
   1054       operator[](last_spec) const noexcept;
   1055 
   1056       friend constexpr bool
   1057       operator==(const weekday& __x, const weekday& __y) noexcept
   1058       { return __x._M_wd == __y._M_wd; }
   1059 
   1060       friend constexpr weekday
   1061       operator+(const weekday& __x, const days& __y) noexcept
   1062       {
   1063 	return weekday{__detail::__add_modulo<7>(__x._M_wd, __y.count())};
   1064       }
   1065 
   1066       friend constexpr weekday
   1067       operator+(const days& __x, const weekday& __y) noexcept
   1068       { return __y + __x; }
   1069 
   1070       friend constexpr weekday
   1071       operator-(const weekday& __x, const days& __y) noexcept
   1072       {
   1073 	return weekday{__detail::__sub_modulo<7>(__x._M_wd, __y.count())};
   1074       }
   1075 
   1076       friend constexpr days
   1077       operator-(const weekday& __x, const weekday& __y) noexcept
   1078       {
   1079 	const auto __n = __x.c_encoding() - __y.c_encoding();
   1080 	return static_cast<int>(__n) >= 0 ? days{__n} : days{__n + 7};
   1081       }
   1082     };
   1083 
   1084     inline constexpr weekday Sunday{0};
   1085     inline constexpr weekday Monday{1};
   1086     inline constexpr weekday Tuesday{2};
   1087     inline constexpr weekday Wednesday{3};
   1088     inline constexpr weekday Thursday{4};
   1089     inline constexpr weekday Friday{5};
   1090     inline constexpr weekday Saturday{6};
   1091 
   1092     // WEEKDAY_INDEXED
   1093 
   1094     class weekday_indexed
   1095     {
   1096     private:
   1097       chrono::weekday _M_wd;
   1098       unsigned char _M_index;
   1099 
   1100     public:
   1101       weekday_indexed() = default;
   1102 
   1103       constexpr
   1104       weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
   1105       : _M_wd(__wd), _M_index(__index)
   1106       { }
   1107 
   1108       constexpr chrono::weekday
   1109       weekday() const noexcept
   1110       { return _M_wd; }
   1111 
   1112       constexpr unsigned
   1113       index() const noexcept
   1114       { return _M_index; };
   1115 
   1116       constexpr bool
   1117       ok() const noexcept
   1118       { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
   1119 
   1120       friend constexpr bool
   1121       operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
   1122       { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
   1123 
   1124       friend constexpr month_weekday
   1125       operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
   1126 
   1127       friend constexpr month_weekday
   1128       operator/(int __m, const weekday_indexed& __wdi) noexcept;
   1129 
   1130       friend constexpr month_weekday
   1131       operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
   1132 
   1133       friend constexpr month_weekday
   1134       operator/(const weekday_indexed& __wdi, int __m) noexcept;
   1135 
   1136       friend constexpr year_month_weekday
   1137       operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
   1138     };
   1139 
   1140     constexpr weekday_indexed
   1141     weekday::operator[](unsigned __index) const noexcept
   1142     { return {*this, __index}; }
   1143 
   1144     // WEEKDAY_LAST
   1145 
   1146     class weekday_last
   1147     {
   1148     private:
   1149       chrono::weekday _M_wd;
   1150 
   1151     public:
   1152       explicit constexpr
   1153       weekday_last(const chrono::weekday& __wd) noexcept
   1154       : _M_wd{__wd}
   1155       { }
   1156 
   1157       constexpr chrono::weekday
   1158       weekday() const noexcept
   1159       { return _M_wd; }
   1160 
   1161       constexpr bool
   1162       ok() const noexcept
   1163       { return _M_wd.ok(); }
   1164 
   1165       friend constexpr bool
   1166       operator==(const weekday_last& __x, const weekday_last& __y) noexcept
   1167       { return __x.weekday() == __y.weekday(); }
   1168 
   1169       friend constexpr month_weekday_last
   1170       operator/(int __m, const weekday_last& __wdl) noexcept;
   1171 
   1172       friend constexpr month_weekday_last
   1173       operator/(const weekday_last& __wdl, int __m) noexcept;
   1174 
   1175       friend constexpr year_month_weekday_last
   1176       operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
   1177     };
   1178 
   1179     constexpr weekday_last
   1180     weekday::operator[](last_spec) const noexcept
   1181     { return weekday_last{*this}; }
   1182 
   1183     // MONTH_DAY
   1184 
   1185     class month_day
   1186     {
   1187     private:
   1188       chrono::month _M_m;
   1189       chrono::day _M_d;
   1190 
   1191     public:
   1192       month_day() = default;
   1193 
   1194       constexpr
   1195       month_day(const chrono::month& __m, const chrono::day& __d) noexcept
   1196       : _M_m{__m}, _M_d{__d}
   1197       { }
   1198 
   1199       constexpr chrono::month
   1200       month() const noexcept
   1201       { return _M_m; }
   1202 
   1203       constexpr chrono::day
   1204       day() const noexcept
   1205       { return _M_d; }
   1206 
   1207       constexpr bool
   1208       ok() const noexcept
   1209       {
   1210 	return _M_m.ok()
   1211 	  && 1u <= unsigned(_M_d)
   1212 	  && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
   1213       }
   1214 
   1215       friend constexpr bool
   1216       operator==(const month_day& __x, const month_day& __y) noexcept
   1217       { return __x.month() == __y.month() && __x.day() == __y.day(); }
   1218 
   1219       friend constexpr strong_ordering
   1220       operator<=>(const month_day& __x, const month_day& __y) noexcept
   1221 	= default;
   1222 
   1223       friend constexpr month_day
   1224       operator/(const chrono::month& __m, const chrono::day& __d) noexcept
   1225       { return {__m, __d}; }
   1226 
   1227       friend constexpr month_day
   1228       operator/(const chrono::month& __m, int __d) noexcept
   1229       { return {__m, chrono::day(unsigned(__d))}; }
   1230 
   1231       friend constexpr month_day
   1232       operator/(int __m, const chrono::day& __d) noexcept
   1233       { return {chrono::month(unsigned(__m)), __d}; }
   1234 
   1235       friend constexpr month_day
   1236       operator/(const chrono::day& __d, const chrono::month& __m) noexcept
   1237       { return {__m, __d}; }
   1238 
   1239       friend constexpr month_day
   1240       operator/(const chrono::day& __d, int __m) noexcept
   1241       { return {chrono::month(unsigned(__m)), __d}; }
   1242 
   1243       friend constexpr year_month_day
   1244       operator/(int __y, const month_day& __md) noexcept;
   1245 
   1246       friend constexpr year_month_day
   1247       operator/(const month_day& __md, int __y) noexcept;
   1248     };
   1249 
   1250     // MONTH_DAY_LAST
   1251 
   1252     class month_day_last
   1253     {
   1254     private:
   1255       chrono::month _M_m;
   1256 
   1257     public:
   1258       explicit constexpr
   1259       month_day_last(const chrono::month& __m) noexcept
   1260       : _M_m{__m}
   1261       { }
   1262 
   1263       constexpr chrono::month
   1264       month() const noexcept
   1265       { return _M_m; }
   1266 
   1267       constexpr bool
   1268       ok() const noexcept
   1269       { return _M_m.ok(); }
   1270 
   1271       friend constexpr bool
   1272       operator==(const month_day_last& __x, const month_day_last& __y) noexcept
   1273       { return __x.month() == __y.month(); }
   1274 
   1275       friend constexpr strong_ordering
   1276       operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
   1277 	= default;
   1278 
   1279       friend constexpr month_day_last
   1280       operator/(const chrono::month& __m, last_spec) noexcept
   1281       { return month_day_last{__m}; }
   1282 
   1283       friend constexpr month_day_last
   1284       operator/(int __m, last_spec) noexcept
   1285       { return chrono::month(unsigned(__m)) / last; }
   1286 
   1287       friend constexpr month_day_last
   1288       operator/(last_spec, const chrono::month& __m) noexcept
   1289       { return __m / last; }
   1290 
   1291       friend constexpr month_day_last
   1292       operator/(last_spec, int __m) noexcept
   1293       { return __m / last; }
   1294 
   1295       friend constexpr year_month_day_last
   1296       operator/(int __y, const month_day_last& __mdl) noexcept;
   1297 
   1298       friend constexpr year_month_day_last
   1299       operator/(const month_day_last& __mdl, int __y) noexcept;
   1300     };
   1301 
   1302     // MONTH_WEEKDAY
   1303 
   1304     class month_weekday
   1305     {
   1306     private:
   1307       chrono::month _M_m;
   1308       chrono::weekday_indexed _M_wdi;
   1309 
   1310     public:
   1311       constexpr
   1312       month_weekday(const chrono::month& __m,
   1313 		    const chrono::weekday_indexed& __wdi) noexcept
   1314       : _M_m{__m}, _M_wdi{__wdi}
   1315       { }
   1316 
   1317       constexpr chrono::month
   1318       month() const noexcept
   1319       { return _M_m; }
   1320 
   1321       constexpr chrono::weekday_indexed
   1322       weekday_indexed() const noexcept
   1323       { return _M_wdi; }
   1324 
   1325       constexpr bool
   1326       ok() const noexcept
   1327       { return _M_m.ok() && _M_wdi.ok(); }
   1328 
   1329       friend constexpr bool
   1330       operator==(const month_weekday& __x, const month_weekday& __y) noexcept
   1331       {
   1332 	return __x.month() == __y.month()
   1333 	  && __x.weekday_indexed() == __y.weekday_indexed();
   1334       }
   1335 
   1336       friend constexpr month_weekday
   1337       operator/(const chrono::month& __m,
   1338 		const chrono::weekday_indexed& __wdi) noexcept
   1339       { return {__m, __wdi}; }
   1340 
   1341       friend constexpr month_weekday
   1342       operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
   1343       { return chrono::month(unsigned(__m)) / __wdi; }
   1344 
   1345       friend constexpr month_weekday
   1346       operator/(const chrono::weekday_indexed& __wdi,
   1347 		const chrono::month& __m) noexcept
   1348       { return __m / __wdi; }
   1349 
   1350       friend constexpr month_weekday
   1351       operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
   1352       { return __m / __wdi; }
   1353 
   1354       friend constexpr year_month_weekday
   1355       operator/(int __y, const month_weekday& __mwd) noexcept;
   1356 
   1357       friend constexpr year_month_weekday
   1358       operator/(const month_weekday& __mwd, int __y) noexcept;
   1359     };
   1360 
   1361     // MONTH_WEEKDAY_LAST
   1362 
   1363     class month_weekday_last
   1364     {
   1365     private:
   1366       chrono::month _M_m;
   1367       chrono::weekday_last _M_wdl;
   1368 
   1369     public:
   1370       constexpr
   1371       month_weekday_last(const chrono::month& __m,
   1372 			 const chrono::weekday_last& __wdl) noexcept
   1373       :_M_m{__m}, _M_wdl{__wdl}
   1374       { }
   1375 
   1376       constexpr chrono::month
   1377       month() const noexcept
   1378       { return _M_m; }
   1379 
   1380       constexpr chrono::weekday_last
   1381       weekday_last() const noexcept
   1382       { return _M_wdl; }
   1383 
   1384       constexpr bool
   1385       ok() const noexcept
   1386       { return _M_m.ok() && _M_wdl.ok(); }
   1387 
   1388       friend constexpr bool
   1389       operator==(const month_weekday_last& __x,
   1390 		 const month_weekday_last& __y) noexcept
   1391       {
   1392 	return __x.month() == __y.month()
   1393 	  && __x.weekday_last() == __y.weekday_last();
   1394       }
   1395 
   1396       friend constexpr month_weekday_last
   1397       operator/(const chrono::month& __m,
   1398 		const chrono::weekday_last& __wdl) noexcept
   1399       { return {__m, __wdl}; }
   1400 
   1401       friend constexpr month_weekday_last
   1402       operator/(int __m, const chrono::weekday_last& __wdl) noexcept
   1403       { return chrono::month(unsigned(__m)) / __wdl; }
   1404 
   1405       friend constexpr month_weekday_last
   1406       operator/(const chrono::weekday_last& __wdl,
   1407 		const chrono::month& __m) noexcept
   1408       { return __m / __wdl; }
   1409 
   1410       friend constexpr month_weekday_last
   1411       operator/(const chrono::weekday_last& __wdl, int __m) noexcept
   1412       { return chrono::month(unsigned(__m)) / __wdl; }
   1413 
   1414       friend constexpr year_month_weekday_last
   1415       operator/(int __y, const month_weekday_last& __mwdl) noexcept;
   1416 
   1417       friend constexpr year_month_weekday_last
   1418       operator/(const month_weekday_last& __mwdl, int __y) noexcept;
   1419     };
   1420 
   1421     // YEAR_MONTH
   1422 
   1423     namespace __detail
   1424     {
   1425       // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
   1426       // addition/subtraction operator overloads like so:
   1427       //
   1428       //   Constraints: if the argument supplied by the caller for the months
   1429       //   parameter is convertible to years, its implicit conversion sequence
   1430       //   to years is worse than its implicit conversion sequence to months.
   1431       //
   1432       // We realize this constraint by templatizing the 'months'-based
   1433       // overloads (using a dummy defaulted template parameter), so that
   1434       // overload resolution doesn't select the 'months'-based overload unless
   1435       // the implicit conversion sequence to 'months' is better than that to
   1436       // 'years'.
   1437       using __months_years_conversion_disambiguator = void;
   1438     }
   1439 
   1440     class year_month
   1441     {
   1442     private:
   1443       chrono::year _M_y;
   1444       chrono::month _M_m;
   1445 
   1446     public:
   1447       year_month() = default;
   1448 
   1449       constexpr
   1450       year_month(const chrono::year& __y, const chrono::month& __m) noexcept
   1451       : _M_y{__y}, _M_m{__m}
   1452       { }
   1453 
   1454       constexpr chrono::year
   1455       year() const noexcept
   1456       { return _M_y; }
   1457 
   1458       constexpr chrono::month
   1459       month() const noexcept
   1460       { return _M_m; }
   1461 
   1462       template<typename = __detail::__months_years_conversion_disambiguator>
   1463 	constexpr year_month&
   1464 	operator+=(const months& __dm) noexcept
   1465 	{
   1466 	  *this = *this + __dm;
   1467 	  return *this;
   1468 	}
   1469 
   1470       template<typename = __detail::__months_years_conversion_disambiguator>
   1471 	constexpr year_month&
   1472 	operator-=(const months& __dm) noexcept
   1473 	{
   1474 	  *this = *this - __dm;
   1475 	  return *this;
   1476 	}
   1477 
   1478       constexpr year_month&
   1479       operator+=(const years& __dy)  noexcept
   1480       {
   1481 	*this = *this + __dy;
   1482 	return *this;
   1483       }
   1484 
   1485       constexpr year_month&
   1486       operator-=(const years& __dy)  noexcept
   1487       {
   1488 	*this = *this - __dy;
   1489 	return *this;
   1490       }
   1491 
   1492       constexpr bool
   1493       ok() const noexcept
   1494       { return _M_y.ok() && _M_m.ok(); }
   1495 
   1496       friend constexpr bool
   1497       operator==(const year_month& __x, const year_month& __y) noexcept
   1498       { return __x.year() == __y.year() && __x.month() == __y.month(); }
   1499 
   1500       friend constexpr strong_ordering
   1501       operator<=>(const year_month& __x, const year_month& __y) noexcept
   1502 	= default;
   1503 
   1504       template<typename = __detail::__months_years_conversion_disambiguator>
   1505 	friend constexpr year_month
   1506 	operator+(const year_month& __ym, const months& __dm) noexcept
   1507 	{
   1508 	  // TODO: Optimize?
   1509 	  auto __m = __ym.month() + __dm;
   1510 	  auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
   1511 	  auto __y = (__i < 0
   1512 		      ? __ym.year() + years{(__i - 11) / 12}
   1513 		      : __ym.year() + years{__i / 12});
   1514 	  return __y / __m;
   1515 	}
   1516 
   1517       template<typename = __detail::__months_years_conversion_disambiguator>
   1518 	friend constexpr year_month
   1519 	operator+(const months& __dm, const year_month& __ym) noexcept
   1520 	{ return __ym + __dm; }
   1521 
   1522       template<typename = __detail::__months_years_conversion_disambiguator>
   1523 	friend constexpr year_month
   1524 	operator-(const year_month& __ym, const months& __dm) noexcept
   1525 	{ return __ym + -__dm; }
   1526 
   1527       friend constexpr months
   1528       operator-(const year_month& __x, const year_month& __y) noexcept
   1529       {
   1530 	return (__x.year() - __y.year()
   1531 		+ months{static_cast<int>(unsigned{__x.month()})
   1532 			 - static_cast<int>(unsigned{__y.month()})});
   1533       }
   1534 
   1535       friend constexpr year_month
   1536       operator+(const year_month& __ym, const years& __dy) noexcept
   1537       { return (__ym.year() + __dy) / __ym.month(); }
   1538 
   1539       friend constexpr year_month
   1540       operator+(const years& __dy, const year_month& __ym) noexcept
   1541       { return __ym + __dy; }
   1542 
   1543       friend constexpr year_month
   1544       operator-(const year_month& __ym, const years& __dy) noexcept
   1545       { return __ym + -__dy; }
   1546 
   1547       friend constexpr year_month
   1548       operator/(const chrono::year& __y, const chrono::month& __m) noexcept
   1549       { return {__y, __m}; }
   1550 
   1551       friend constexpr year_month
   1552       operator/(const chrono::year& __y, int __m) noexcept
   1553       { return {__y, chrono::month(unsigned(__m))}; }
   1554 
   1555       friend constexpr year_month_day
   1556       operator/(const year_month& __ym, int __d) noexcept;
   1557 
   1558       friend constexpr year_month_day_last
   1559       operator/(const year_month& __ym, last_spec) noexcept;
   1560     };
   1561 
   1562     // YEAR_MONTH_DAY
   1563 
   1564     class year_month_day
   1565     {
   1566     private:
   1567       chrono::year _M_y;
   1568       chrono::month _M_m;
   1569       chrono::day _M_d;
   1570 
   1571       static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
   1572 
   1573       constexpr days _M_days_since_epoch() const noexcept;
   1574 
   1575     public:
   1576       year_month_day() = default;
   1577 
   1578       constexpr
   1579       year_month_day(const chrono::year& __y, const chrono::month& __m,
   1580 		     const chrono::day& __d) noexcept
   1581       : _M_y{__y}, _M_m{__m}, _M_d{__d}
   1582       { }
   1583 
   1584       constexpr
   1585       year_month_day(const year_month_day_last& __ymdl) noexcept;
   1586 
   1587       constexpr
   1588       year_month_day(const sys_days& __dp) noexcept
   1589       : year_month_day(_S_from_days(__dp.time_since_epoch()))
   1590       { }
   1591 
   1592       explicit constexpr
   1593       year_month_day(const local_days& __dp) noexcept
   1594       : year_month_day(sys_days{__dp.time_since_epoch()})
   1595       { }
   1596 
   1597       template<typename = __detail::__months_years_conversion_disambiguator>
   1598 	constexpr year_month_day&
   1599 	operator+=(const months& __m) noexcept
   1600 	{
   1601 	  *this = *this + __m;
   1602 	  return *this;
   1603 	}
   1604 
   1605       template<typename = __detail::__months_years_conversion_disambiguator>
   1606 	constexpr year_month_day&
   1607 	operator-=(const months& __m) noexcept
   1608 	{
   1609 	  *this = *this - __m;
   1610 	  return *this;
   1611 	}
   1612 
   1613       constexpr year_month_day&
   1614       operator+=(const years& __y) noexcept
   1615       {
   1616 	*this = *this + __y;
   1617 	return *this;
   1618       }
   1619 
   1620       constexpr year_month_day&
   1621       operator-=(const years& __y) noexcept
   1622       {
   1623 	*this = *this - __y;
   1624 	return *this;
   1625       }
   1626 
   1627       constexpr chrono::year
   1628       year() const noexcept
   1629       { return _M_y; }
   1630 
   1631       constexpr chrono::month
   1632       month() const noexcept
   1633       { return _M_m; }
   1634 
   1635       constexpr chrono::day
   1636       day() const noexcept
   1637       { return _M_d; }
   1638 
   1639       constexpr
   1640       operator sys_days() const noexcept
   1641       { return sys_days{_M_days_since_epoch()}; }
   1642 
   1643       explicit constexpr
   1644       operator local_days() const noexcept
   1645       { return local_days{sys_days{*this}.time_since_epoch()}; }
   1646 
   1647       constexpr bool ok() const noexcept;
   1648 
   1649       friend constexpr bool
   1650       operator==(const year_month_day& __x, const year_month_day& __y) noexcept
   1651       {
   1652 	return __x.year() == __y.year()
   1653 	  && __x.month() == __y.month()
   1654 	  && __x.day() == __y.day();
   1655       }
   1656 
   1657       friend constexpr strong_ordering
   1658       operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
   1659 	= default;
   1660 
   1661       template<typename = __detail::__months_years_conversion_disambiguator>
   1662 	friend constexpr year_month_day
   1663 	operator+(const year_month_day& __ymd, const months& __dm) noexcept
   1664 	{ return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
   1665 
   1666       template<typename = __detail::__months_years_conversion_disambiguator>
   1667 	friend constexpr year_month_day
   1668 	operator+(const months& __dm, const year_month_day& __ymd) noexcept
   1669 	{ return __ymd + __dm; }
   1670 
   1671       friend constexpr year_month_day
   1672       operator+(const year_month_day& __ymd, const years& __dy) noexcept
   1673       { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
   1674 
   1675       friend constexpr year_month_day
   1676       operator+(const years& __dy, const year_month_day& __ymd) noexcept
   1677       { return __ymd + __dy; }
   1678 
   1679       template<typename = __detail::__months_years_conversion_disambiguator>
   1680 	friend constexpr year_month_day
   1681 	operator-(const year_month_day& __ymd, const months& __dm) noexcept
   1682 	{ return __ymd + -__dm; }
   1683 
   1684       friend constexpr year_month_day
   1685       operator-(const year_month_day& __ymd, const years& __dy) noexcept
   1686       { return __ymd + -__dy; }
   1687 
   1688       friend constexpr year_month_day
   1689       operator/(const year_month& __ym, const chrono::day& __d) noexcept
   1690       { return {__ym.year(), __ym.month(), __d}; }
   1691 
   1692       friend constexpr year_month_day
   1693       operator/(const year_month& __ym, int __d) noexcept
   1694       { return __ym / chrono::day{unsigned(__d)}; }
   1695 
   1696       friend constexpr year_month_day
   1697       operator/(const chrono::year& __y, const month_day& __md) noexcept
   1698       { return __y / __md.month() / __md.day(); }
   1699 
   1700       friend constexpr year_month_day
   1701       operator/(int __y, const month_day& __md) noexcept
   1702       { return chrono::year{__y} / __md; }
   1703 
   1704       friend constexpr year_month_day
   1705       operator/(const month_day& __md, const chrono::year& __y) noexcept
   1706       { return __y / __md; }
   1707 
   1708       friend constexpr year_month_day
   1709       operator/(const month_day& __md, int __y) noexcept
   1710       { return chrono::year(__y) / __md; }
   1711     };
   1712 
   1713     // Construct from days since 1970/01/01.
   1714     // Proposition 6.3 of Neri and Schneider,
   1715     // "Euclidean Affine Functions and Applications to Calendar Algorithms".
   1716     // https://arxiv.org/abs/2102.06959
   1717     constexpr year_month_day
   1718     year_month_day::_S_from_days(const days& __dp) noexcept
   1719     {
   1720       constexpr auto __z2    = static_cast<uint32_t>(-1468000);
   1721       constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
   1722 
   1723       const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
   1724 
   1725       const auto __n1 = 4 * __r0 + 3;
   1726       const auto __q1 = __n1 / 146097;
   1727       const auto __r1 = __n1 % 146097 / 4;
   1728 
   1729       constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
   1730       const auto __n2 = 4 * __r1 + 3;
   1731       const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
   1732       const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
   1733       const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
   1734 
   1735       constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
   1736       const auto __n3 = 2141 * __r2 + 197913;
   1737       const auto __q3 = __n3 / __p16;
   1738       const auto __r3 = __n3 % __p16 / 2141;
   1739 
   1740       const auto __y0 = 100 * __q1 + __q2;
   1741       const auto __m0 = __q3;
   1742       const auto __d0 = __r3;
   1743 
   1744       const auto __j  = __r2 >= 306;
   1745       const auto __y1 = __y0 + __j;
   1746       const auto __m1 = __j ? __m0 - 12 : __m0;
   1747       const auto __d1 = __d0 + 1;
   1748 
   1749       return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
   1750 			    chrono::month{__m1}, chrono::day{__d1}};
   1751     }
   1752 
   1753     // Days since 1970/01/01.
   1754     // Proposition 6.2 of Neri and Schneider,
   1755     // "Euclidean Affine Functions and Applications to Calendar Algorithms".
   1756     // https://arxiv.org/abs/2102.06959
   1757     constexpr days
   1758     year_month_day::_M_days_since_epoch() const noexcept
   1759     {
   1760       auto constexpr __z2    = static_cast<uint32_t>(-1468000);
   1761       auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
   1762 
   1763       const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
   1764       const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
   1765       const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
   1766 
   1767       const auto __j  = static_cast<uint32_t>(__m1 < 3);
   1768       const auto __y0 = __y1 - __j;
   1769       const auto __m0 = __j ? __m1 + 12 : __m1;
   1770       const auto __d0 = __d1 - 1;
   1771 
   1772       const auto __q1 = __y0 / 100;
   1773       const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
   1774       const auto __mc = (979 *__m0 - 2919) / 32;
   1775       const auto __dc = __d0;
   1776 
   1777       return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
   1778     }
   1779 
   1780     // YEAR_MONTH_DAY_LAST
   1781 
   1782     class year_month_day_last
   1783     {
   1784     private:
   1785       chrono::year _M_y;
   1786       chrono::month_day_last _M_mdl;
   1787 
   1788     public:
   1789       constexpr
   1790       year_month_day_last(const chrono::year& __y,
   1791 			  const chrono::month_day_last& __mdl) noexcept
   1792       : _M_y{__y}, _M_mdl{__mdl}
   1793       { }
   1794 
   1795       template<typename = __detail::__months_years_conversion_disambiguator>
   1796 	constexpr year_month_day_last&
   1797 	operator+=(const months& __m) noexcept
   1798 	{
   1799 	  *this = *this + __m;
   1800 	  return *this;
   1801 	}
   1802 
   1803       template<typename = __detail::__months_years_conversion_disambiguator>
   1804 	constexpr year_month_day_last&
   1805 	operator-=(const months& __m) noexcept
   1806 	{
   1807 	  *this = *this - __m;
   1808 	  return *this;
   1809 	}
   1810 
   1811       constexpr year_month_day_last&
   1812       operator+=(const years& __y)  noexcept
   1813       {
   1814 	*this = *this + __y;
   1815 	return *this;
   1816       }
   1817 
   1818       constexpr year_month_day_last&
   1819       operator-=(const years& __y)  noexcept
   1820       {
   1821 	*this = *this - __y;
   1822 	return *this;
   1823       }
   1824 
   1825       constexpr chrono::year
   1826       year() const noexcept
   1827       { return _M_y; }
   1828 
   1829       constexpr chrono::month
   1830       month() const noexcept
   1831       { return _M_mdl.month(); }
   1832 
   1833       constexpr chrono::month_day_last
   1834       month_day_last() const noexcept
   1835       { return _M_mdl; }
   1836 
   1837       // Return A day representing the last day of this year, month pair.
   1838       constexpr chrono::day
   1839       day() const noexcept
   1840       {
   1841 	const auto __m = static_cast<unsigned>(month());
   1842 
   1843 	// The result is unspecified if __m < 1 or __m > 12.  Hence, assume
   1844 	// 1 <= __m <= 12.  For __m != 2, day() == 30 or day() == 31 or, in
   1845 	// other words, day () == 30 | b, where b is in {0, 1}.
   1846 
   1847 	// If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
   1848 	// odd.  Hence, b = __m & 1 = (__m ^ 0) & 1.
   1849 
   1850 	// If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
   1851 	// even.  Hence, b = (__m ^ 1) & 1.
   1852 
   1853 	// Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
   1854 	// __m >= 8, that is, c = __m >> 3.
   1855 
   1856 	// Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
   1857 	// calculation is unnecessary.
   1858 
   1859 	// The performance of this implementation does not depend on look-up
   1860 	// tables being on the L1 cache.
   1861 	return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
   1862 	  : _M_y.is_leap() ? 29 : 28};
   1863       }
   1864 
   1865       constexpr
   1866       operator sys_days() const noexcept
   1867       { return sys_days{year() / month() / day()}; }
   1868 
   1869       explicit constexpr
   1870       operator local_days() const noexcept
   1871       { return local_days{sys_days{*this}.time_since_epoch()}; }
   1872 
   1873       constexpr bool
   1874       ok() const noexcept
   1875       { return _M_y.ok() && _M_mdl.ok(); }
   1876 
   1877       friend constexpr bool
   1878       operator==(const year_month_day_last& __x,
   1879 		 const year_month_day_last& __y) noexcept
   1880       {
   1881 	return __x.year() == __y.year()
   1882 	  && __x.month_day_last() == __y.month_day_last();
   1883       }
   1884 
   1885       friend constexpr strong_ordering
   1886       operator<=>(const year_month_day_last& __x,
   1887 		  const year_month_day_last& __y) noexcept
   1888 	= default;
   1889 
   1890       template<typename = __detail::__months_years_conversion_disambiguator>
   1891 	friend constexpr year_month_day_last
   1892 	operator+(const year_month_day_last& __ymdl,
   1893 		  const months& __dm) noexcept
   1894 	{ return (__ymdl.year() / __ymdl.month() + __dm) / last; }
   1895 
   1896       template<typename = __detail::__months_years_conversion_disambiguator>
   1897 	friend constexpr year_month_day_last
   1898 	operator+(const months& __dm,
   1899 		  const year_month_day_last& __ymdl) noexcept
   1900 	{ return __ymdl + __dm; }
   1901 
   1902       template<typename = __detail::__months_years_conversion_disambiguator>
   1903 	friend constexpr year_month_day_last
   1904 	operator-(const year_month_day_last& __ymdl,
   1905 		  const months& __dm) noexcept
   1906 	{ return __ymdl + -__dm; }
   1907 
   1908       friend constexpr year_month_day_last
   1909       operator+(const year_month_day_last& __ymdl,
   1910 		const years& __dy) noexcept
   1911       { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
   1912 
   1913       friend constexpr year_month_day_last
   1914       operator+(const years& __dy,
   1915 		const year_month_day_last& __ymdl) noexcept
   1916       { return __ymdl + __dy; }
   1917 
   1918       friend constexpr year_month_day_last
   1919       operator-(const year_month_day_last& __ymdl,
   1920 		const years& __dy) noexcept
   1921       { return __ymdl + -__dy; }
   1922 
   1923       friend constexpr year_month_day_last
   1924       operator/(const year_month& __ym, last_spec) noexcept
   1925       { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
   1926 
   1927       friend constexpr year_month_day_last
   1928       operator/(const chrono::year& __y,
   1929 		const chrono::month_day_last& __mdl) noexcept
   1930       { return {__y, __mdl}; }
   1931 
   1932       friend constexpr year_month_day_last
   1933       operator/(int __y, const chrono::month_day_last& __mdl) noexcept
   1934       { return chrono::year(__y) / __mdl; }
   1935 
   1936       friend constexpr year_month_day_last
   1937       operator/(const chrono::month_day_last& __mdl,
   1938 		const chrono::year& __y) noexcept
   1939       { return __y / __mdl; }
   1940 
   1941       friend constexpr year_month_day_last
   1942       operator/(const chrono::month_day_last& __mdl, int __y) noexcept
   1943       { return chrono::year(__y) / __mdl; }
   1944     };
   1945 
   1946     // year_month_day ctor from year_month_day_last
   1947     constexpr
   1948     year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
   1949     : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
   1950     { }
   1951 
   1952     constexpr bool
   1953     year_month_day::ok() const noexcept
   1954     {
   1955       if (!_M_y.ok() || !_M_m.ok())
   1956 	return false;
   1957       return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
   1958     }
   1959 
   1960     // YEAR_MONTH_WEEKDAY
   1961 
   1962     class year_month_weekday
   1963     {
   1964     private:
   1965       chrono::year _M_y;
   1966       chrono::month _M_m;
   1967       chrono::weekday_indexed _M_wdi;
   1968 
   1969       static constexpr year_month_weekday
   1970       _S_from_sys_days(const sys_days& __dp)
   1971       {
   1972 	year_month_day __ymd{__dp};
   1973 	chrono::weekday __wd{__dp};
   1974 	auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
   1975 	return {__ymd.year(), __ymd.month(), __index};
   1976       }
   1977 
   1978     public:
   1979       year_month_weekday() = default;
   1980 
   1981       constexpr
   1982       year_month_weekday(const chrono::year& __y, const chrono::month& __m,
   1983 			 const chrono::weekday_indexed& __wdi) noexcept
   1984       : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
   1985       { }
   1986 
   1987       constexpr
   1988       year_month_weekday(const sys_days& __dp) noexcept
   1989       : year_month_weekday{_S_from_sys_days(__dp)}
   1990       { }
   1991 
   1992       explicit constexpr
   1993       year_month_weekday(const local_days& __dp) noexcept
   1994       : year_month_weekday{sys_days{__dp.time_since_epoch()}}
   1995       { }
   1996 
   1997       template<typename = __detail::__months_years_conversion_disambiguator>
   1998 	constexpr year_month_weekday&
   1999 	operator+=(const months& __m) noexcept
   2000 	{
   2001 	  *this = *this + __m;
   2002 	  return *this;
   2003 	}
   2004 
   2005       template<typename = __detail::__months_years_conversion_disambiguator>
   2006 	constexpr year_month_weekday&
   2007 	operator-=(const months& __m) noexcept
   2008 	{
   2009 	  *this = *this - __m;
   2010 	  return *this;
   2011 	}
   2012 
   2013       constexpr year_month_weekday&
   2014       operator+=(const years& __y) noexcept
   2015       {
   2016 	*this = *this + __y;
   2017 	return *this;
   2018       }
   2019 
   2020       constexpr year_month_weekday&
   2021       operator-=(const years& __y) noexcept
   2022       {
   2023 	*this = *this - __y;
   2024 	return *this;
   2025       }
   2026 
   2027       constexpr chrono::year
   2028       year() const noexcept
   2029       { return _M_y; }
   2030 
   2031       constexpr chrono::month
   2032       month() const noexcept
   2033       { return _M_m; }
   2034 
   2035       constexpr chrono::weekday
   2036       weekday() const noexcept
   2037       { return _M_wdi.weekday(); }
   2038 
   2039       constexpr unsigned
   2040       index() const noexcept
   2041       { return _M_wdi.index(); }
   2042 
   2043       constexpr chrono::weekday_indexed
   2044       weekday_indexed() const noexcept
   2045       { return _M_wdi; }
   2046 
   2047       constexpr
   2048       operator sys_days() const noexcept
   2049       {
   2050 	auto __d = sys_days{year() / month() / 1};
   2051 	return __d + (weekday() - chrono::weekday(__d)
   2052 		      + days{(static_cast<int>(index())-1)*7});
   2053       }
   2054 
   2055       explicit constexpr
   2056       operator local_days() const noexcept
   2057       { return local_days{sys_days{*this}.time_since_epoch()}; }
   2058 
   2059       constexpr bool
   2060       ok() const noexcept
   2061       {
   2062 	if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
   2063 	  return false;
   2064 	if (_M_wdi.index() <= 4)
   2065 	  return true;
   2066 	days __d = (_M_wdi.weekday()
   2067 		    - chrono::weekday{sys_days{_M_y / _M_m / 1}}
   2068 		    + days((_M_wdi.index()-1)*7 + 1));
   2069 	__glibcxx_assert(__d.count() >= 1);
   2070 	return (unsigned)__d.count() <= (unsigned)(_M_y / _M_m / last).day();
   2071       }
   2072 
   2073       friend constexpr bool
   2074       operator==(const year_month_weekday& __x,
   2075 		 const year_month_weekday& __y) noexcept
   2076       {
   2077 	return __x.year() == __y.year()
   2078 	  && __x.month() == __y.month()
   2079 	  && __x.weekday_indexed() == __y.weekday_indexed();
   2080       }
   2081 
   2082       template<typename = __detail::__months_years_conversion_disambiguator>
   2083 	friend constexpr year_month_weekday
   2084 	operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
   2085 	{
   2086 	  return ((__ymwd.year() / __ymwd.month() + __dm)
   2087 		  / __ymwd.weekday_indexed());
   2088 	}
   2089 
   2090       template<typename = __detail::__months_years_conversion_disambiguator>
   2091 	friend constexpr year_month_weekday
   2092 	operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
   2093 	{ return __ymwd + __dm; }
   2094 
   2095       friend constexpr year_month_weekday
   2096       operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
   2097       { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
   2098 
   2099       friend constexpr year_month_weekday
   2100       operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
   2101       { return __ymwd + __dy; }
   2102 
   2103       template<typename = __detail::__months_years_conversion_disambiguator>
   2104 	friend constexpr year_month_weekday
   2105 	operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
   2106 	{ return __ymwd + -__dm; }
   2107 
   2108       friend constexpr year_month_weekday
   2109       operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
   2110       { return __ymwd + -__dy; }
   2111 
   2112       friend constexpr year_month_weekday
   2113       operator/(const year_month& __ym,
   2114 		const chrono::weekday_indexed& __wdi) noexcept
   2115       { return {__ym.year(), __ym.month(), __wdi}; }
   2116 
   2117       friend constexpr year_month_weekday
   2118       operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
   2119       { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
   2120 
   2121       friend constexpr year_month_weekday
   2122       operator/(int __y, const month_weekday& __mwd) noexcept
   2123       { return chrono::year(__y) / __mwd; }
   2124 
   2125       friend constexpr year_month_weekday
   2126       operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
   2127       { return __y / __mwd; }
   2128 
   2129       friend constexpr year_month_weekday
   2130       operator/(const month_weekday& __mwd, int __y) noexcept
   2131       { return chrono::year(__y) / __mwd; }
   2132     };
   2133 
   2134     // YEAR_MONTH_WEEKDAY_LAST
   2135 
   2136     class year_month_weekday_last
   2137     {
   2138     private:
   2139       chrono::year _M_y;
   2140       chrono::month _M_m;
   2141       chrono::weekday_last _M_wdl;
   2142 
   2143     public:
   2144       constexpr
   2145       year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
   2146 			      const chrono::weekday_last& __wdl) noexcept
   2147       : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
   2148       { }
   2149 
   2150       template<typename = __detail::__months_years_conversion_disambiguator>
   2151 	constexpr year_month_weekday_last&
   2152 	operator+=(const months& __m) noexcept
   2153 	{
   2154 	  *this = *this + __m;
   2155 	  return *this;
   2156 	}
   2157 
   2158       template<typename = __detail::__months_years_conversion_disambiguator>
   2159 	constexpr year_month_weekday_last&
   2160 	operator-=(const months& __m) noexcept
   2161 	{
   2162 	  *this = *this - __m;
   2163 	  return *this;
   2164 	}
   2165 
   2166       constexpr year_month_weekday_last&
   2167       operator+=(const years& __y)  noexcept
   2168       {
   2169 	*this = *this + __y;
   2170 	return *this;
   2171       }
   2172 
   2173       constexpr year_month_weekday_last&
   2174       operator-=(const years& __y)  noexcept
   2175       {
   2176 	*this = *this - __y;
   2177 	return *this;
   2178       }
   2179 
   2180       constexpr chrono::year
   2181       year() const noexcept
   2182       { return _M_y; }
   2183 
   2184       constexpr chrono::month
   2185       month() const noexcept
   2186       { return _M_m; }
   2187 
   2188       constexpr chrono::weekday
   2189       weekday() const noexcept
   2190       { return _M_wdl.weekday(); }
   2191 
   2192       constexpr chrono::weekday_last
   2193       weekday_last() const noexcept
   2194       { return _M_wdl; }
   2195 
   2196       constexpr
   2197       operator sys_days() const noexcept
   2198       {
   2199 	const auto __d = sys_days{_M_y / _M_m / last};
   2200 	return sys_days{(__d - (chrono::weekday{__d}
   2201 				- _M_wdl.weekday())).time_since_epoch()};
   2202       }
   2203 
   2204       explicit constexpr
   2205       operator local_days() const noexcept
   2206       { return local_days{sys_days{*this}.time_since_epoch()}; }
   2207 
   2208       constexpr bool
   2209       ok() const noexcept
   2210       { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
   2211 
   2212       friend constexpr bool
   2213       operator==(const year_month_weekday_last& __x,
   2214 		 const year_month_weekday_last& __y) noexcept
   2215       {
   2216 	return __x.year() == __y.year()
   2217 	  && __x.month() == __y.month()
   2218 	  && __x.weekday_last() == __y.weekday_last();
   2219       }
   2220 
   2221       template<typename = __detail::__months_years_conversion_disambiguator>
   2222 	friend constexpr year_month_weekday_last
   2223 	operator+(const year_month_weekday_last& __ymwdl,
   2224 		  const months& __dm) noexcept
   2225 	{
   2226 	  return ((__ymwdl.year() / __ymwdl.month() + __dm)
   2227 		  / __ymwdl.weekday_last());
   2228 	}
   2229 
   2230       template<typename = __detail::__months_years_conversion_disambiguator>
   2231 	friend constexpr year_month_weekday_last
   2232 	operator+(const months& __dm,
   2233 		  const year_month_weekday_last& __ymwdl) noexcept
   2234 	{ return __ymwdl + __dm; }
   2235 
   2236       friend constexpr year_month_weekday_last
   2237       operator+(const year_month_weekday_last& __ymwdl,
   2238 		const years& __dy) noexcept
   2239       { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
   2240 
   2241       friend constexpr year_month_weekday_last
   2242       operator+(const years& __dy,
   2243 		const year_month_weekday_last& __ymwdl) noexcept
   2244       { return __ymwdl + __dy; }
   2245 
   2246       template<typename = __detail::__months_years_conversion_disambiguator>
   2247 	friend constexpr year_month_weekday_last
   2248 	operator-(const year_month_weekday_last& __ymwdl,
   2249 		  const months& __dm) noexcept
   2250 	{ return __ymwdl + -__dm; }
   2251 
   2252       friend constexpr year_month_weekday_last
   2253       operator-(const year_month_weekday_last& __ymwdl,
   2254 		const years& __dy) noexcept
   2255       { return __ymwdl + -__dy; }
   2256 
   2257       friend constexpr year_month_weekday_last
   2258       operator/(const year_month& __ym,
   2259 		const chrono::weekday_last& __wdl) noexcept
   2260       { return {__ym.year(), __ym.month(), __wdl}; }
   2261 
   2262       friend constexpr year_month_weekday_last
   2263       operator/(const chrono::year& __y,
   2264 		const chrono::month_weekday_last& __mwdl) noexcept
   2265       { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
   2266 
   2267       friend constexpr year_month_weekday_last
   2268       operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
   2269       { return chrono::year(__y) / __mwdl; }
   2270 
   2271       friend constexpr year_month_weekday_last
   2272       operator/(const chrono::month_weekday_last& __mwdl,
   2273 		const chrono::year& __y) noexcept
   2274       { return __y / __mwdl; }
   2275 
   2276       friend constexpr year_month_weekday_last
   2277       operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
   2278       { return chrono::year(__y) / __mwdl; }
   2279     };
   2280 
   2281     // HH_MM_SS
   2282 
   2283     /// @cond undocumented
   2284     namespace __detail
   2285     {
   2286       consteval long long
   2287       __pow10(unsigned __n)
   2288       {
   2289 	long long __r = 1;
   2290 	while (__n-- > 0)
   2291 	  __r *= 10;
   2292 	return __r;
   2293       }
   2294 
   2295       template<typename _Duration> struct __utc_leap_second;
   2296     }
   2297     /// @endcond
   2298 
   2299     /** Utility for splitting a duration into hours, minutes, and seconds
   2300      *
   2301      * This is a convenience type that provides accessors for the constituent
   2302      * parts (hours, minutes, seconds and subseconds) of a duration.
   2303      *
   2304      * @since C++20
   2305      */
   2306     template<typename _Duration>
   2307       class hh_mm_ss
   2308       {
   2309 	static_assert( __is_duration<_Duration>::value );
   2310 
   2311       private:
   2312 	static consteval int
   2313 	_S_fractional_width()
   2314 	{
   2315 	  auto __den = _Duration::period::den;
   2316 	  const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
   2317 	  __den >>= __multiplicity_2;
   2318 	  int __multiplicity_5 = 0;
   2319 	  while ((__den % 5) == 0)
   2320 	    {
   2321 	      ++__multiplicity_5;
   2322 	      __den /= 5;
   2323 	    }
   2324 	  if (__den != 1)
   2325 	    return 6;
   2326 
   2327 	  int __width = (__multiplicity_2 > __multiplicity_5
   2328 			 ? __multiplicity_2 : __multiplicity_5);
   2329 	  if (__width > 18)
   2330 	    __width = 18;
   2331 	  return __width;
   2332 	}
   2333 
   2334 	constexpr
   2335 	hh_mm_ss(_Duration __d, bool __is_neg)
   2336 	: _M_h (duration_cast<chrono::hours>(__d)),
   2337 	  _M_m (duration_cast<chrono::minutes>(__d - hours())),
   2338 	  _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
   2339 	  _M_is_neg(__is_neg)
   2340 	{
   2341 	  auto __ss = __d - hours() - minutes() - seconds();
   2342 	  if constexpr (treat_as_floating_point_v<typename precision::rep>)
   2343 	    _M_ss._M_r = __ss.count();
   2344 	  else if constexpr (precision::period::den != 1)
   2345 	    _M_ss._M_r = duration_cast<precision>(__ss).count();
   2346 	}
   2347 
   2348 	static constexpr _Duration
   2349 	_S_abs(_Duration __d)
   2350 	{
   2351 	  if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
   2352 	    return chrono::abs(__d);
   2353 	  else
   2354 	    return __d;
   2355 	}
   2356 
   2357       public:
   2358 	static constexpr unsigned fractional_width = {_S_fractional_width()};
   2359 
   2360 	using precision
   2361 	  = duration<common_type_t<typename _Duration::rep,
   2362 				   chrono::seconds::rep>,
   2363 		     ratio<1, __detail::__pow10(fractional_width)>>;
   2364 
   2365 	constexpr hh_mm_ss() noexcept = default;
   2366 
   2367 	constexpr explicit
   2368 	hh_mm_ss(_Duration __d)
   2369 	: hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
   2370 	{ }
   2371 
   2372 	constexpr bool
   2373 	is_negative() const noexcept
   2374 	{
   2375 	  if constexpr (!_S_is_unsigned)
   2376 	    return _M_is_neg;
   2377 	  else
   2378 	    return false;
   2379 	}
   2380 
   2381 	constexpr chrono::hours
   2382 	hours() const noexcept
   2383 	{ return _M_h; }
   2384 
   2385 	constexpr chrono::minutes
   2386 	minutes() const noexcept
   2387 	{ return _M_m; }
   2388 
   2389 	constexpr chrono::seconds
   2390 	seconds() const noexcept
   2391 	{ return _M_s; }
   2392 
   2393 	constexpr precision
   2394 	subseconds() const noexcept
   2395 	{ return static_cast<precision>(_M_ss); }
   2396 
   2397 	constexpr explicit
   2398 	operator precision() const noexcept
   2399 	{ return to_duration(); }
   2400 
   2401 	constexpr precision
   2402 	to_duration() const noexcept
   2403 	{
   2404 	  if constexpr (!_S_is_unsigned)
   2405 	    if (_M_is_neg)
   2406 	      return -(_M_h + _M_m + _M_s + subseconds());
   2407 	  return _M_h + _M_m + _M_s + subseconds();
   2408 	}
   2409 
   2410       private:
   2411 	static constexpr bool _S_is_unsigned
   2412 	  = __and_v<is_integral<typename _Duration::rep>,
   2413 		    is_unsigned<typename _Duration::rep>>;
   2414 
   2415 	template<typename _Ratio>
   2416 	  using __byte_duration = duration<unsigned char, _Ratio>;
   2417 
   2418 	// The type of the _M_ss member that holds the subsecond precision.
   2419 	template<typename _Dur>
   2420 	  struct __subseconds
   2421 	  {
   2422 	    typename _Dur::rep _M_r{};
   2423 
   2424 	    constexpr explicit
   2425 	    operator _Dur() const noexcept
   2426 	    { return _Dur(_M_r); }
   2427 	  };
   2428 
   2429 	// An empty class if this precision doesn't need subseconds.
   2430 	template<typename _Rep>
   2431 	  requires (!treat_as_floating_point_v<_Rep>)
   2432 	  struct __subseconds<duration<_Rep, ratio<1>>>
   2433 	  {
   2434 	    constexpr explicit
   2435 	    operator duration<_Rep, ratio<1>>() const noexcept
   2436 	    { return {}; }
   2437 	  };
   2438 
   2439 	template<typename _Rep, typename _Period>
   2440 	  requires (!treat_as_floating_point_v<_Rep>)
   2441 	    && ratio_less_v<_Period, ratio<1, 1>>
   2442 	    && ratio_greater_equal_v<_Period, ratio<1, 250>>
   2443 	  struct __subseconds<duration<_Rep, _Period>>
   2444 	  {
   2445 	    unsigned char _M_r{};
   2446 
   2447 	    constexpr explicit
   2448 	    operator duration<_Rep, _Period>() const noexcept
   2449 	    { return duration<_Rep, _Period>(_M_r); }
   2450 	  };
   2451 
   2452 	template<typename _Rep, typename _Period>
   2453 	  requires (!treat_as_floating_point_v<_Rep>)
   2454 	    && ratio_less_v<_Period, ratio<1, 250>>
   2455 	    && ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
   2456 	  struct __subseconds<duration<_Rep, _Period>>
   2457 	  {
   2458 	    uint_least32_t _M_r{};
   2459 
   2460 	    constexpr explicit
   2461 	    operator duration<_Rep, _Period>() const noexcept
   2462 	    { return duration<_Rep, _Period>(_M_r); }
   2463 	  };
   2464 
   2465 	chrono::hours		    _M_h{};
   2466 	__byte_duration<ratio<60>>  _M_m{};
   2467 	__byte_duration<ratio<1>>   _M_s{};
   2468 	bool			    _M_is_neg{};
   2469 	__subseconds<precision>	    _M_ss{};
   2470 
   2471 	template<typename> friend struct __detail::__utc_leap_second;
   2472       };
   2473 
   2474     /// @cond undocumented
   2475     namespace __detail
   2476     {
   2477       // Represents a time that is within a leap second insertion.
   2478       template<typename _Duration>
   2479 	struct __utc_leap_second
   2480 	{
   2481 	  explicit
   2482 	  __utc_leap_second(const sys_time<_Duration>& __s)
   2483 	  : _M_date(chrono::floor<days>(__s)), _M_time(__s - _M_date)
   2484 	  {
   2485 	    ++_M_time._M_s;
   2486 	  }
   2487 
   2488 	  sys_days _M_date;
   2489 	  hh_mm_ss<common_type_t<_Duration, days>> _M_time;
   2490 	};
   2491     }
   2492     /// @endcond
   2493 
   2494     // 12/24 HOURS FUNCTIONS
   2495 
   2496     constexpr bool
   2497     is_am(const hours& __h) noexcept
   2498     { return 0h <= __h && __h <= 11h; }
   2499 
   2500     constexpr bool
   2501     is_pm(const hours& __h) noexcept
   2502     { return 12h <= __h && __h <= 23h; }
   2503 
   2504     constexpr hours
   2505     make12(const hours& __h) noexcept
   2506     {
   2507       if (__h == 0h)
   2508 	return 12h;
   2509       else if (__h > 12h)
   2510 	return __h - 12h;
   2511       return __h;
   2512     }
   2513 
   2514     constexpr hours
   2515     make24(const hours& __h, bool __is_pm) noexcept
   2516     {
   2517       if (!__is_pm)
   2518 	{
   2519 	  if (__h == 12h)
   2520 	    return 0h;
   2521 	  else
   2522 	    return __h;
   2523 	}
   2524       else
   2525 	{
   2526 	  if (__h == 12h)
   2527 	    return __h;
   2528 	  else
   2529 	    return __h + 12h;
   2530 	}
   2531     }
   2532 
   2533 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   2534     // C++20 [time.zones] Time zones
   2535 
   2536     struct tzdb;
   2537 
   2538     struct sys_info
   2539     {
   2540       sys_seconds begin;
   2541       sys_seconds end;
   2542       seconds offset;
   2543       minutes save;
   2544       string abbrev;
   2545     };
   2546 
   2547     struct local_info
   2548     {
   2549       static constexpr int unique      = 0;
   2550       static constexpr int nonexistent = 1;
   2551       static constexpr int ambiguous   = 2;
   2552 
   2553       int result;
   2554       sys_info first;
   2555       sys_info second;
   2556     };
   2557 
   2558     class nonexistent_local_time : public runtime_error
   2559     {
   2560     public:
   2561       template<typename _Duration>
   2562 	nonexistent_local_time(const local_time<_Duration>& __tp,
   2563 			       const local_info& __i)
   2564 	: runtime_error(_S_make_what_str(__tp, __i))
   2565 	{ __glibcxx_assert(__i.result == local_info::nonexistent); }
   2566 
   2567     private:
   2568       template<typename _Duration>
   2569 	static string
   2570 	_S_make_what_str(const local_time<_Duration>& __tp,
   2571 			 const local_info& __i)
   2572 	{
   2573 	  std::ostringstream __os;
   2574 	  __os << __tp << " is in a gap between\n"
   2575 	       << local_seconds(__i.first.end.time_since_epoch())
   2576 	       + __i.first.offset << ' ' << __i.first.abbrev << " and\n"
   2577 	       << local_seconds(__i.second.begin.time_since_epoch())
   2578 	       + __i.second.offset << ' ' << __i.second.abbrev
   2579 	       << " which are both equivalent to\n"
   2580 	       << __i.first.end << " UTC";
   2581 	  return std::move(__os).str();
   2582 	}
   2583     };
   2584 
   2585     class ambiguous_local_time : public runtime_error
   2586     {
   2587     public:
   2588       template<typename _Duration>
   2589 	ambiguous_local_time(const local_time<_Duration>& __tp,
   2590 			     const local_info& __i)
   2591 	: runtime_error(_S_make_what_str(__tp, __i))
   2592 	{ __glibcxx_assert(__i.result == local_info::ambiguous); }
   2593 
   2594     private:
   2595       template<typename _Duration>
   2596 	static string
   2597 	_S_make_what_str(const local_time<_Duration>& __tp,
   2598 			 const local_info& __i)
   2599 	{
   2600 	  std::ostringstream __os;
   2601 	  __os << __tp << " is ambiguous.  It could be\n"
   2602 	       << __tp << ' ' << __i.first.abbrev << " == "
   2603 	       << __tp - __i.first.offset << " UTC or\n"
   2604 	       << __tp << ' ' << __i.second.abbrev << " == "
   2605 	       << __tp - __i.second.offset << " UTC";
   2606 	  return std::move(__os).str();
   2607 	}
   2608     };
   2609 
   2610     template<typename _Duration>
   2611       [[noreturn]] void
   2612       __throw_bad_local_time(const local_time<_Duration>& __tp,
   2613 			     const local_info& __i)
   2614       {
   2615 #if __cpp_exceptions
   2616 	if (__i.result == local_info::nonexistent)
   2617 	  throw nonexistent_local_time(__tp, __i);
   2618 	throw ambiguous_local_time(__tp, __i);
   2619 #else
   2620 	__builtin_abort();
   2621 #endif
   2622       }
   2623 
   2624     enum class choose { earliest, latest };
   2625 
   2626     class time_zone
   2627     {
   2628     public:
   2629       time_zone(time_zone&&) = default;
   2630       time_zone& operator=(time_zone&&) = default;
   2631 
   2632       ~time_zone();
   2633 
   2634       [[nodiscard]]
   2635       string_view name() const noexcept { return _M_name; }
   2636 
   2637       template<typename _Duration>
   2638 	sys_info
   2639 	get_info(const sys_time<_Duration>& __st) const
   2640 	{ return _M_get_sys_info(chrono::floor<seconds>(__st)); }
   2641 
   2642       template<typename _Duration>
   2643 	local_info
   2644 	get_info(const local_time<_Duration>& __tp) const
   2645 	{ return _M_get_local_info(chrono::floor<seconds>(__tp)); }
   2646 
   2647       template<typename _Duration>
   2648 	sys_time<common_type_t<_Duration, seconds>>
   2649 	to_sys(const local_time<_Duration>& __tp) const
   2650 	{
   2651 	  local_info __info = get_info(__tp);
   2652 
   2653 	  if (__info.result != local_info::unique)
   2654 	    __throw_bad_local_time(__tp, __info);
   2655 
   2656 	  return sys_time<_Duration>(__tp.time_since_epoch())
   2657 		   - __info.first.offset;
   2658 	}
   2659 
   2660       template<typename _Duration>
   2661 	sys_time<common_type_t<_Duration, seconds>>
   2662 	to_sys(const local_time<_Duration>& __tp, choose __z) const
   2663 	{
   2664 	  local_info __info = get_info(__tp);
   2665 
   2666 	  if (__info.result == local_info::nonexistent)
   2667 	    return __info.first.end; // Last second of the previous sys_info.
   2668 
   2669 	  sys_time<_Duration> __st(__tp.time_since_epoch());
   2670 
   2671 	  if (__info.result == local_info::ambiguous && __z == choose::latest)
   2672 	    return __st - __info.second.offset; // Time in the later sys_info.
   2673 	  // else if __z == earliest, use __info.first.offset as below:
   2674 
   2675 	  return __st - __info.first.offset;
   2676 	}
   2677 
   2678       template<typename _Duration>
   2679 	local_time<common_type_t<_Duration, seconds>>
   2680 	to_local(const sys_time<_Duration>& __tp) const
   2681 	{
   2682 	  auto __d = (__tp + get_info(__tp).offset).time_since_epoch();
   2683 	  return local_time<common_type_t<_Duration, seconds>>(__d);
   2684 	}
   2685 
   2686       [[nodiscard]] friend bool
   2687       operator==(const time_zone& __x, const time_zone& __y) noexcept
   2688       { return __x._M_name == __y._M_name; }
   2689 
   2690       [[nodiscard]] friend strong_ordering
   2691       operator<=>(const time_zone& __x, const time_zone& __y) noexcept
   2692       { return __x._M_name <=> __y._M_name; }
   2693 
   2694     private:
   2695       sys_info _M_get_sys_info(sys_seconds) const;
   2696       local_info _M_get_local_info(local_seconds) const;
   2697 
   2698       friend const tzdb& reload_tzdb();
   2699       friend struct tzdb;
   2700       friend class tzdb_list;
   2701 
   2702       struct _Impl;
   2703 
   2704       explicit time_zone(unique_ptr<_Impl> __p);
   2705       string _M_name;
   2706       unique_ptr<_Impl> _M_impl;
   2707     };
   2708 
   2709     const time_zone* locate_zone(string_view __tz_name);
   2710     const time_zone* current_zone();
   2711 
   2712     /** The list of `chrono::tzdb` objects
   2713      *
   2714      * A single object of this type is constructed by the C++ runtime,
   2715      * and can be accessed by calling `chrono::get_tzdb_list()`.
   2716      *
   2717      * The front of the list is the current `tzdb` object and can be accessed
   2718      * via `chrono::get_tzdb_list().front()` or `chrono::get_tzdb()` or
   2719      * `*chrono::get_tzdb_list().begin()`.
   2720      *
   2721      * The `chrono::reload_tzdb()` function will check for a newer version
   2722      * and if found, insert it at the front of the list.
   2723      *
   2724      * @since C++20
   2725      */
   2726     class tzdb_list
   2727     {
   2728       struct _Node;
   2729 
   2730     public:
   2731       tzdb_list(const tzdb_list&) = delete;
   2732       tzdb_list& operator=(const tzdb_list&) = delete;
   2733 
   2734       /** An iterator into the `tzdb_list`
   2735        *
   2736        * As a extension, in libstdc++ each `tzdb` is reference-counted
   2737        * and the `const_iterator` type shares ownership of the object it
   2738        * refers to. This ensures that a `tzdb` erased from the list will
   2739        * not be destroyed while there is an iterator that refers to it.
   2740        */
   2741       class const_iterator
   2742       {
   2743       public:
   2744 	using value_type        = tzdb;
   2745 	using reference         = const tzdb&;
   2746 	using pointer           = const tzdb*;
   2747 	using difference_type   = ptrdiff_t;
   2748 	using iterator_category = forward_iterator_tag;
   2749 
   2750 	constexpr const_iterator() = default;
   2751 	const_iterator(const const_iterator&) = default;
   2752 	const_iterator(const_iterator&&) = default;
   2753 	const_iterator& operator=(const const_iterator&) = default;
   2754 	const_iterator& operator=(const_iterator&&) = default;
   2755 
   2756 	reference operator*() const noexcept;
   2757 	pointer operator->() const noexcept { return &**this; }
   2758 	const_iterator& operator++();
   2759 	const_iterator operator++(int);
   2760 
   2761 	bool operator==(const const_iterator&) const noexcept = default;
   2762 
   2763       private:
   2764 	explicit const_iterator(const shared_ptr<_Node>&) noexcept;
   2765 
   2766 	friend class tzdb_list;
   2767 
   2768 	shared_ptr<_Node> _M_node;
   2769 	void* _M_reserved = nullptr;
   2770       };
   2771 
   2772       /** Access the current `tzdb` at the front of the list.
   2773        *
   2774        * This returns a reference to the same object as `chrono::get_tzdb()`.
   2775        *
   2776        * @returns A reference to the current tzdb object.
   2777        * @since C++20
   2778        */
   2779       const tzdb& front() const noexcept;
   2780 
   2781       /** Remove the tzdb object _after_ the one the iterator refers to.
   2782        *
   2783        * Calling this function concurrently with any of `front()`, `begin()`,
   2784        * or `end()` does not cause a data race, but in general this function
   2785        * is not thread-safe. The behaviour may be undefined if erasing an
   2786        * element from the list while another thread is calling the same
   2787        * function, or incrementing an iterator into the list, or accessing
   2788        * the element being erased (unless it is accessed through an iterator).
   2789        *
   2790        * @param __p A dereferenceable iterator.
   2791        * @returns An iterator the element after the one that was erased
   2792        *          (or `end()` if there is no such element).
   2793        * @since C++20
   2794        */
   2795       const_iterator erase_after(const_iterator __p);
   2796 
   2797       const_iterator begin() const noexcept;
   2798       const_iterator end() const noexcept { return {}; }
   2799       const_iterator cbegin() const noexcept { return begin(); }
   2800       const_iterator cend() const noexcept { return end(); }
   2801 
   2802     private:
   2803       constexpr explicit tzdb_list(nullptr_t);
   2804 
   2805       friend tzdb_list& get_tzdb_list();
   2806       friend const tzdb& get_tzdb();
   2807       friend const tzdb& reload_tzdb();
   2808       friend struct tzdb;
   2809       friend class leap_second;
   2810       friend struct time_zone::_Impl;
   2811       friend class time_zone_link;
   2812     };
   2813 
   2814     class time_zone_link
   2815     {
   2816     public:
   2817       time_zone_link(time_zone_link&&) = default;
   2818       time_zone_link& operator=(time_zone_link&&) = default;
   2819 
   2820       string_view name() const noexcept { return _M_name; }
   2821       string_view target() const noexcept { return _M_target; }
   2822 
   2823       friend bool
   2824       operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
   2825       { return __x.name() == __y.name(); }
   2826 
   2827       friend strong_ordering
   2828       operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
   2829       { return __x.name() <=> __y.name(); }
   2830 
   2831     private:
   2832       friend const tzdb& reload_tzdb();
   2833       friend struct tzdb_list::_Node;
   2834 
   2835       explicit time_zone_link(nullptr_t) { }
   2836 
   2837       string _M_name;
   2838       string _M_target;
   2839     };
   2840 
   2841     class leap_second
   2842     {
   2843     public:
   2844       leap_second(const leap_second&) = default;
   2845       leap_second& operator=(const leap_second&) = default;
   2846 
   2847       [[nodiscard]]
   2848       constexpr sys_seconds
   2849       date() const noexcept
   2850       {
   2851 	if (_M_s >= _M_s.zero()) [[likely]]
   2852 	  return sys_seconds(_M_s);
   2853 	return sys_seconds(-_M_s);
   2854       }
   2855 
   2856       [[nodiscard]]
   2857       constexpr seconds
   2858       value() const noexcept
   2859       {
   2860 	if (_M_s >= _M_s.zero()) [[likely]]
   2861 	  return seconds(1);
   2862 	return seconds(-1);
   2863       }
   2864 
   2865       // This can be defaulted because the database will never contain two
   2866       // leap_second objects with the same date but different signs.
   2867       [[nodiscard]] friend constexpr bool
   2868       operator==(const leap_second&, const leap_second&) noexcept = default;
   2869 
   2870       [[nodiscard]] friend constexpr strong_ordering
   2871       operator<=>(const leap_second& __x, const leap_second& __y) noexcept
   2872       { return __x.date() <=> __y.date(); }
   2873 
   2874       template<typename _Duration>
   2875 	[[nodiscard]] friend constexpr bool
   2876 	operator==(const leap_second& __x,
   2877 		   const sys_time<_Duration>& __y) noexcept
   2878 	{ return __x.date() == __y; }
   2879 
   2880       template<typename _Duration>
   2881 	[[nodiscard]] friend constexpr bool
   2882 	operator<(const leap_second& __x,
   2883 		  const sys_time<_Duration>& __y) noexcept
   2884 	{ return __x.date() < __y; }
   2885 
   2886       template<typename _Duration>
   2887 	[[nodiscard]] friend constexpr bool
   2888 	operator<(const sys_time<_Duration>& __x,
   2889 		  const leap_second& __y) noexcept
   2890 	{ return __x < __y.date(); }
   2891 
   2892       template<typename _Duration>
   2893 	[[nodiscard]] friend constexpr bool
   2894 	operator>(const leap_second& __x,
   2895 		  const sys_time<_Duration>& __y) noexcept
   2896 	{ return __y < __x.date(); }
   2897 
   2898       template<typename _Duration>
   2899 	[[nodiscard]] friend constexpr bool
   2900 	operator>(const sys_time<_Duration>& __x,
   2901 		  const leap_second& __y) noexcept
   2902 	{ return __y.date() < __x; }
   2903 
   2904       template<typename _Duration>
   2905 	[[nodiscard]] friend constexpr bool
   2906 	operator<=(const leap_second& __x,
   2907 		   const sys_time<_Duration>& __y) noexcept
   2908 	{ return !(__y < __x.date()); }
   2909 
   2910       template<typename _Duration>
   2911 	[[nodiscard]] friend constexpr bool
   2912 	operator<=(const sys_time<_Duration>& __x,
   2913 		   const leap_second& __y) noexcept
   2914 	{ return !(__y.date() < __x); }
   2915 
   2916       template<typename _Duration>
   2917 	[[nodiscard]] friend constexpr bool
   2918 	operator>=(const leap_second& __x,
   2919 		   const sys_time<_Duration>& __y) noexcept
   2920 	{ return !(__x.date() < __y); }
   2921 
   2922       template<typename _Duration>
   2923 	[[nodiscard]] friend constexpr bool
   2924 	operator>=(const sys_time<_Duration>& __x,
   2925 		   const leap_second& __y) noexcept
   2926 	{ return !(__x < __y.date()); }
   2927 
   2928       template<three_way_comparable_with<seconds> _Duration>
   2929 	[[nodiscard]] friend constexpr auto
   2930 	operator<=>(const leap_second& __x,
   2931 		    const sys_time<_Duration>& __y) noexcept
   2932 	{ return __x.date() <=> __y; }
   2933 
   2934     private:
   2935       explicit leap_second(seconds::rep __s) : _M_s(__s) { }
   2936 
   2937       friend struct tzdb_list::_Node;
   2938 
   2939       friend const tzdb& reload_tzdb();
   2940 
   2941       template<typename _Duration>
   2942 	friend leap_second_info
   2943 	get_leap_second_info(const utc_time<_Duration>&);
   2944 
   2945       seconds _M_s; // == date().time_since_epoch() * value().count()
   2946     };
   2947 
   2948     template<class _Tp> struct zoned_traits { };
   2949 
   2950     template<>
   2951       struct zoned_traits<const time_zone*>
   2952       {
   2953 	static const time_zone*
   2954 	default_zone()
   2955 	{ return std::chrono::locate_zone("UTC"); }
   2956 
   2957 	static const time_zone*
   2958 	locate_zone(string_view __name)
   2959 	{ return std::chrono::locate_zone(__name); }
   2960       };
   2961 
   2962     struct tzdb
   2963     {
   2964       string version;
   2965       _GLIBCXX_STD_C::vector<time_zone> zones;
   2966       _GLIBCXX_STD_C::vector<time_zone_link> links;
   2967       _GLIBCXX_STD_C::vector<leap_second> leap_seconds;
   2968 
   2969       const time_zone*
   2970       locate_zone(string_view __tz_name) const;
   2971 
   2972       const time_zone*
   2973       current_zone() const;
   2974 
   2975     private:
   2976       friend const tzdb& reload_tzdb();
   2977       friend class time_zone;
   2978       friend struct tzdb_list::_Node;
   2979     };
   2980 
   2981     tzdb_list& get_tzdb_list();
   2982     const tzdb& get_tzdb();
   2983 
   2984     const tzdb& reload_tzdb();
   2985     string remote_version();
   2986 
   2987     template<typename _Duration, typename _TimeZonePtr = const time_zone*>
   2988       class zoned_time
   2989       {
   2990 	static_assert(__is_duration_v<_Duration>);
   2991 
   2992 	using _Traits = zoned_traits<_TimeZonePtr>;
   2993 
   2994 	// Every constructor that accepts a string_view as its first parameter
   2995 	// does not participate in class template argument deduction.
   2996 	using string_view = type_identity_t<std::string_view>;
   2997 
   2998       public:
   2999 	using duration = common_type_t<_Duration, seconds>;
   3000 
   3001 	zoned_time() requires requires { _Traits::default_zone(); }
   3002 	{ }
   3003 
   3004 	zoned_time(const zoned_time&) = default;
   3005 	zoned_time& operator=(const zoned_time&) = default;
   3006 
   3007 	zoned_time(const sys_time<_Duration>& __st)
   3008 	  requires requires { _Traits::default_zone(); }
   3009 	: _M_tp(__st)
   3010 	{ }
   3011 
   3012 	explicit
   3013 	zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
   3014 
   3015 	explicit
   3016 	zoned_time(string_view __name)
   3017 	  requires requires {
   3018 	    _TimeZonePtr{_Traits::locate_zone(std::string_view{})};
   3019 	  }
   3020 	: _M_zone(_Traits::locate_zone(__name))
   3021 	{ }
   3022 
   3023 	template<typename _Duration2>
   3024 	  zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)
   3025 	  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
   3026 	  : _M_zone(__zt._M_zone), _M_tp(__zt._M_tp)
   3027 	  { }
   3028 
   3029 	zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
   3030 	: _M_zone(std::move(__z)), _M_tp(__st)
   3031 	{ }
   3032 
   3033 	zoned_time(string_view __name, const sys_time<_Duration>& __st)
   3034 	: zoned_time(_Traits::locate_zone(__name), __st)
   3035 	{ }
   3036 
   3037 	zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp)
   3038 	requires requires {
   3039 	  { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
   3040 	}
   3041 	: _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp))
   3042 	{ }
   3043 
   3044 	zoned_time(string_view __name, const local_time<_Duration>& __tp)
   3045 	requires requires (_TimeZonePtr __z) {
   3046 	  { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
   3047 	  { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
   3048 	}
   3049 	: zoned_time(_Traits::locate_zone(__name), __tp)
   3050 	{ }
   3051 
   3052 	zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp,
   3053 		   choose __c)
   3054 	requires requires {
   3055 	  { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
   3056 	}
   3057 	: _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp, __c))
   3058 	{ }
   3059 
   3060 	zoned_time(string_view __name, const local_time<_Duration>& __tp,
   3061 		   choose __c)
   3062 	requires requires (_TimeZonePtr __z) {
   3063 	  { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
   3064 	  { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
   3065 	}
   3066 	: _M_zone(_Traits::locate_zone(__name)),
   3067 	  _M_tp(_M_zone->to_sys(__tp, __c))
   3068 	{ }
   3069 
   3070 	template<typename _Duration2, typename _TimeZonePtr2>
   3071 	  zoned_time(_TimeZonePtr __z,
   3072 		     const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
   3073 	  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
   3074 	  : _M_zone(__z), _M_tp(__zt._M_tp)
   3075 	  { }
   3076 
   3077 	template<typename _Duration2, typename _TimeZonePtr2>
   3078 	  zoned_time(_TimeZonePtr __z,
   3079 		     const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
   3080 		     choose)
   3081 	  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
   3082 	  : _M_zone(__z), _M_tp(__zt._M_tp)
   3083 	  { }
   3084 
   3085 	template<typename _Duration2, typename _TimeZonePtr2>
   3086 	  zoned_time(string_view __name,
   3087 		     const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
   3088 	  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
   3089 	  && requires {
   3090 	    { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
   3091 	  }
   3092 	  : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
   3093 	  { }
   3094 
   3095 	template<typename _Duration2, typename _TimeZonePtr2>
   3096 	  zoned_time(string_view __name,
   3097 		     const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
   3098 		     choose)
   3099 	  requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
   3100 	  && requires {
   3101 	    { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
   3102 	  }
   3103 	  : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
   3104 	  { }
   3105 
   3106 	zoned_time&
   3107 	operator=(const sys_time<_Duration>& __st)
   3108 	{
   3109 	  _M_tp = __st;
   3110 	  return *this;
   3111 	}
   3112 
   3113 	zoned_time&
   3114 	operator=(const local_time<_Duration>& __lt)
   3115 	{
   3116 	  _M_tp = _M_zone->to_sys(__lt);
   3117 	  return *this;
   3118 	}
   3119 
   3120 	[[nodiscard]]
   3121 	operator sys_time<duration>() const { return _M_tp; }
   3122 
   3123 	[[nodiscard]]
   3124 	explicit operator local_time<duration>() const
   3125 	{ return get_local_time(); }
   3126 
   3127 	[[nodiscard]]
   3128 	_TimeZonePtr
   3129 	get_time_zone() const
   3130 	{ return _M_zone; }
   3131 
   3132 	[[nodiscard]]
   3133 	local_time<duration>
   3134 	get_local_time() const
   3135 	{ return _M_zone->to_local(_M_tp); }
   3136 
   3137 	[[nodiscard]]
   3138 	sys_time<duration>
   3139 	get_sys_time() const
   3140 	{ return _M_tp; }
   3141 
   3142 	[[nodiscard]]
   3143 	sys_info
   3144 	get_info() const
   3145 	{ return _M_zone->get_info(_M_tp); }
   3146 
   3147 	[[nodiscard]] friend bool
   3148 	operator==(const zoned_time&, const zoned_time&) = default;
   3149 
   3150       private:
   3151 	_TimeZonePtr       _M_zone{ _Traits::default_zone() };
   3152 	sys_time<duration> _M_tp{};
   3153 
   3154 	template<typename _Duration2, typename _TimeZonePtr2>
   3155 	  friend class zoned_time;
   3156       };
   3157 
   3158     zoned_time() -> zoned_time<seconds>;
   3159 
   3160     template<typename _Duration>
   3161     zoned_time(sys_time<_Duration>)
   3162       -> zoned_time<common_type_t<_Duration, seconds>>;
   3163 
   3164   /// @cond undocumented
   3165   template<typename _TimeZonePtrOrName>
   3166     using __time_zone_representation
   3167       = __conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,
   3168 			const time_zone*,
   3169 			remove_cvref_t<_TimeZonePtrOrName>>;
   3170   /// @endcond
   3171 
   3172   template<typename _TimeZonePtrOrName>
   3173     zoned_time(_TimeZonePtrOrName&&)
   3174       -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
   3175 
   3176   template<typename _TimeZonePtrOrName, typename _Duration>
   3177     zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)
   3178       -> zoned_time<common_type_t<_Duration, seconds>,
   3179                     __time_zone_representation<_TimeZonePtrOrName>>;
   3180 
   3181   template<typename _TimeZonePtrOrName, typename _Duration>
   3182     zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>,
   3183                choose = choose::earliest)
   3184       -> zoned_time<common_type_t<_Duration, seconds>,
   3185                     __time_zone_representation<_TimeZonePtrOrName>>;
   3186 
   3187   template<typename _Duration, typename _TimeZonePtrOrName,
   3188 	   typename _TimeZonePtr2>
   3189     zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>,
   3190                choose = choose::earliest)
   3191       -> zoned_time<common_type_t<_Duration, seconds>,
   3192                     __time_zone_representation<_TimeZonePtrOrName>>;
   3193 
   3194   template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
   3195     [[nodiscard]]
   3196     inline bool
   3197     operator==(const zoned_time<_Dur1, _TZPtr1>& __x,
   3198 	       const zoned_time<_Dur2, _TZPtr2>& __y)
   3199     {
   3200       return __x.get_time_zone() == __y.get_time_zone()
   3201 	       && __x.get_sys_time() == __y.get_sys_time();
   3202     }
   3203 
   3204     using zoned_seconds = zoned_time<seconds>;
   3205 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   3206 
   3207 namespace __detail
   3208 {
   3209     inline leap_second_info
   3210     __get_leap_second_info(sys_seconds __ss, bool __is_utc)
   3211     {
   3212       if (__ss < sys_seconds{}) [[unlikely]]
   3213 	return {};
   3214 
   3215       const seconds::rep __leaps[] {
   3216 	  78796800, // 1 Jul 1972
   3217 	  94694400, // 1 Jan 1973
   3218 	 126230400, // 1 Jan 1974
   3219 	 157766400, // 1 Jan 1975
   3220 	 189302400, // 1 Jan 1976
   3221 	 220924800, // 1 Jan 1977
   3222 	 252460800, // 1 Jan 1978
   3223 	 283996800, // 1 Jan 1979
   3224 	 315532800, // 1 Jan 1980
   3225 	 362793600, // 1 Jul 1981
   3226 	 394329600, // 1 Jul 1982
   3227 	 425865600, // 1 Jul 1983
   3228 	 489024000, // 1 Jul 1985
   3229 	 567993600, // 1 Jan 1988
   3230 	 631152000, // 1 Jan 1990
   3231 	 662688000, // 1 Jan 1991
   3232 	 709948800, // 1 Jul 1992
   3233 	 741484800, // 1 Jul 1993
   3234 	 773020800, // 1 Jul 1994
   3235 	 820454400, // 1 Jan 1996
   3236 	 867715200, // 1 Jul 1997
   3237 	 915148800, // 1 Jan 1999
   3238 	1136073600, // 1 Jan 2006
   3239 	1230768000, // 1 Jan 2009
   3240 	1341100800, // 1 Jul 2012
   3241 	1435708800, // 1 Jul 2015
   3242 	1483228800, // 1 Jan 2017
   3243       };
   3244       // The list above is known to be valid until (at least) this date
   3245       // and only contains positive leap seconds.
   3246       const sys_seconds __expires(1766880000s); // 2025-12-28 00:00:00 UTC
   3247 
   3248 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   3249       if (__ss > __expires)
   3250 	{
   3251 	  // Use updated leap_seconds from tzdb.
   3252 	  size_t __n = std::size(__leaps);
   3253 
   3254 	  auto __db = get_tzdb_list().begin();
   3255 	  auto __first = __db->leap_seconds.begin() + __n;
   3256 	  auto __last = __db->leap_seconds.end();
   3257 	  auto __pos = std::upper_bound(__first, __last, __ss);
   3258 	  seconds __elapsed(__n);
   3259 	  for (auto __i = __first; __i != __pos; ++__i)
   3260 	    __elapsed += __i->value();
   3261 
   3262 	  if (__is_utc)
   3263 	    {
   3264 	      // Convert utc_time to sys_time:
   3265 	      __ss -= __elapsed;
   3266 	      // See if that sys_time is before (or during) previous leap sec:
   3267 	      if (__pos != __first && __ss < __pos[-1])
   3268 		{
   3269 		  if ((__ss + 1s) >= __pos[-1])
   3270 		    return {true, __elapsed};
   3271 		  __elapsed -= __pos[-1].value();
   3272 		}
   3273 	    }
   3274 	  return {false, __elapsed};
   3275 	}
   3276       else
   3277 #endif
   3278 	{
   3279 	  seconds::rep __s = __ss.time_since_epoch().count();
   3280 	  const seconds::rep* __first = std::begin(__leaps);
   3281 	  const seconds::rep* __last = std::end(__leaps);
   3282 
   3283 	  // Don't bother searching the list if we're after the last one.
   3284 	  if (__s > (__last[-1] + (__last - __first) + 1))
   3285 	    return { false, seconds(__last - __first) };
   3286 
   3287 	  auto __pos = std::upper_bound(__first, __last, __s);
   3288 	  seconds __elapsed{__pos - __first};
   3289 	  if (__is_utc)
   3290 	    {
   3291 	      // Convert utc_time to sys_time:
   3292 	      __s -= __elapsed.count();
   3293 	      // See if that sys_time is before (or during) previous leap sec:
   3294 	      if (__pos != __first && __s < __pos[-1])
   3295 		{
   3296 		  if ((__s + 1) >= __pos[-1])
   3297 		    return {true, __elapsed};
   3298 		  --__elapsed;
   3299 		}
   3300 	    }
   3301 	  return {false, __elapsed};
   3302 	}
   3303     }
   3304 } // namespace __detail
   3305 
   3306     template<typename _Duration>
   3307       [[nodiscard]]
   3308       inline leap_second_info
   3309       get_leap_second_info(const utc_time<_Duration>& __ut)
   3310       {
   3311 	auto __s = chrono::duration_cast<seconds>(__ut.time_since_epoch());
   3312 	return __detail::__get_leap_second_info(sys_seconds(__s), true);
   3313       }
   3314 
   3315     template<typename _Duration>
   3316       [[nodiscard]]
   3317       inline utc_time<common_type_t<_Duration, seconds>>
   3318       utc_clock::from_sys(const sys_time<_Duration>& __t)
   3319       {
   3320 	using _CDur = common_type_t<_Duration, seconds>;
   3321 	auto __s = chrono::time_point_cast<seconds>(__t);
   3322 	const auto __li = __detail::__get_leap_second_info(__s, false);
   3323 	return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
   3324       }
   3325 
   3326     /// @} group chrono
   3327 #endif // C++20
   3328   } // namespace chrono
   3329 
   3330 #if __cplusplus >= 202002L
   3331   inline namespace literals
   3332   {
   3333   inline namespace chrono_literals
   3334   {
   3335     /// @addtogroup chrono
   3336     /// @{
   3337 #pragma GCC diagnostic push
   3338 #pragma GCC diagnostic ignored "-Wliteral-suffix"
   3339     /// Literal suffix for creating chrono::day objects.
   3340     /// @since C++20
   3341     constexpr chrono::day
   3342     operator""d(unsigned long long __d) noexcept
   3343     { return chrono::day{static_cast<unsigned>(__d)}; }
   3344 
   3345     /// Literal suffix for creating chrono::year objects.
   3346     /// @since C++20
   3347     constexpr chrono::year
   3348     operator""y(unsigned long long __y) noexcept
   3349     { return chrono::year{static_cast<int>(__y)}; }
   3350 #pragma GCC diagnostic pop
   3351     /// @}
   3352   } // inline namespace chrono_literals
   3353   } // inline namespace literals
   3354 #endif // C++20
   3355 
   3356 _GLIBCXX_END_NAMESPACE_VERSION
   3357 } // namespace std
   3358 
   3359 #if __cplusplus >= 202002L
   3360 # include <bits/chrono_io.h>
   3361 #endif
   3362 
   3363 #endif // C++11
   3364 
   3365 #endif //_GLIBCXX_CHRONO
   3366