1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008-2022 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 /** @file include/chrono
26 * This is a Standard C++ Library header.
30 #ifndef _GLIBCXX_CHRONO
31 #define _GLIBCXX_CHRONO 1
33 #pragma GCC system_header
35 #include <bits/requires_hosted.h> // for <ctime> and clocks
37 #if __cplusplus < 201103L
38 # include <bits/c++0x_warning.h>
41 #include <bits/chrono.h>
43 #if __cplusplus >= 202002L
48 # include <bits/charconv.h> // __to_chars_len, __to_chars_10_impl
49 # include <bits/stl_algo.h> // upper_bound TODO: move leap_second_info to .so
50 # include <bits/shared_ptr.h>
51 # include <bits/unique_ptr.h>
54 namespace std _GLIBCXX_VISIBILITY(default)
56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 * @defgroup chrono Time
62 * Classes and functions for time.
67 /** @namespace std::chrono
68 * @brief ISO C++ 2011 namespace for date and time utilities
73 #if __cplusplus >= 202002L
74 /// @addtogroup chrono
77 template<typename _Duration>
78 using local_time = time_point<local_t, _Duration>;
79 using local_seconds = local_time<seconds>;
80 using local_days = local_time<days>;
86 template<typename _Duration>
87 using utc_time = time_point<utc_clock, _Duration>;
88 using utc_seconds = utc_time<seconds>;
90 template<typename _Duration>
91 using tai_time = time_point<tai_clock, _Duration>;
92 using tai_seconds = tai_time<seconds>;
94 template<typename _Duration>
95 using gps_time = time_point<gps_clock, _Duration>;
96 using gps_seconds = gps_time<seconds>;
98 template<> struct is_clock<utc_clock> : true_type { };
99 template<> struct is_clock<tai_clock> : true_type { };
100 template<> struct is_clock<gps_clock> : true_type { };
102 template<> inline constexpr bool is_clock_v<utc_clock> = true;
103 template<> inline constexpr bool is_clock_v<tai_clock> = true;
104 template<> inline constexpr bool is_clock_v<gps_clock> = true;
106 struct leap_second_info
112 template<typename _Duration>
114 get_leap_second_info(const utc_time<_Duration>& __ut);
116 /** A clock that measures Universal Coordinated Time (UTC).
118 * The epoch is 1970-01-01 00:00:00.
125 using rep = system_clock::rep;
126 using period = system_clock::period;
127 using duration = chrono::duration<rep, period>;
128 using time_point = chrono::time_point<utc_clock>;
129 static constexpr bool is_steady = false;
133 { return from_sys(system_clock::now()); }
135 template<typename _Duration>
136 static sys_time<common_type_t<_Duration, seconds>>
137 to_sys(const utc_time<_Duration>& __t)
139 using _CDur = common_type_t<_Duration, seconds>;
140 const auto __li = chrono::get_leap_second_info(__t);
141 sys_time<_CDur> __s{__t.time_since_epoch() - seconds{__li.elapsed}};
142 if (__li.is_leap_second)
143 __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
147 template<typename _Duration>
148 static utc_time<common_type_t<_Duration, seconds>>
149 from_sys(const sys_time<_Duration>& __t)
151 using _CDur = common_type_t<_Duration, seconds>;
152 utc_time<_Duration> __u(__t.time_since_epoch());
153 const auto __li = chrono::get_leap_second_info(__u);
154 return utc_time<_CDur>{__u} + seconds{__li.elapsed};
158 /** A clock that measures International Atomic Time.
160 * The epoch is 1958-01-01 00:00:00.
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?
173 // TODO move into lib, use CLOCK_TAI on linux, add extension point.
176 { return from_utc(utc_clock::now()); }
178 template<typename _Duration>
179 static utc_time<common_type_t<_Duration, seconds>>
180 to_utc(const tai_time<_Duration>& __t)
182 using _CDur = common_type_t<_Duration, seconds>;
183 return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
186 template<typename _Duration>
187 static tai_time<common_type_t<_Duration, seconds>>
188 from_utc(const utc_time<_Duration>& __t)
190 using _CDur = common_type_t<_Duration, seconds>;
191 return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
195 /** A clock that measures GPS time.
197 * The epoch is 1980-01-06 00:00:00.
204 using rep = system_clock::rep;
205 using period = system_clock::period;
206 using duration = chrono::duration<rep, period>;
207 using time_point = chrono::time_point<gps_clock>;
208 static constexpr bool is_steady = false; // XXX
210 // TODO move into lib, add extension point.
213 { return from_utc(utc_clock::now()); }
215 template<typename _Duration>
216 static utc_time<common_type_t<_Duration, seconds>>
217 to_utc(const gps_time<_Duration>& __t)
219 using _CDur = common_type_t<_Duration, seconds>;
220 return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
223 template<typename _Duration>
224 static gps_time<common_type_t<_Duration, seconds>>
225 from_utc(const utc_time<_Duration>& __t)
227 using _CDur = common_type_t<_Duration, seconds>;
228 return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
233 template<typename _DestClock, typename _SourceClock>
234 struct clock_time_conversion
237 // Identity conversions
239 template<typename _Clock>
240 struct clock_time_conversion<_Clock, _Clock>
242 template<typename _Duration>
243 time_point<_Clock, _Duration>
244 operator()(const time_point<_Clock, _Duration>& __t) const
249 struct clock_time_conversion<system_clock, system_clock>
251 template<typename _Duration>
253 operator()(const sys_time<_Duration>& __t) const
258 struct clock_time_conversion<utc_clock, utc_clock>
260 template<typename _Duration>
262 operator()(const utc_time<_Duration>& __t) const
266 // Conversions between system_clock and utc_clock
269 struct clock_time_conversion<utc_clock, system_clock>
271 template<typename _Duration>
272 utc_time<common_type_t<_Duration, seconds>>
273 operator()(const sys_time<_Duration>& __t) const
274 { return utc_clock::from_sys(__t); }
278 struct clock_time_conversion<system_clock, utc_clock>
280 template<typename _Duration>
281 sys_time<common_type_t<_Duration, seconds>>
282 operator()(const utc_time<_Duration>& __t) const
283 { return utc_clock::to_sys(__t); }
286 template<typename _Tp, typename _Clock>
287 inline constexpr bool __is_time_point_for_v = false;
289 template<typename _Clock, typename _Duration>
290 inline constexpr bool
291 __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
293 // Conversions between system_clock and other clocks
295 template<typename _SourceClock>
296 struct clock_time_conversion<system_clock, _SourceClock>
298 template<typename _Duration, typename _Src = _SourceClock>
300 operator()(const time_point<_SourceClock, _Duration>& __t) const
301 -> decltype(_Src::to_sys(__t))
303 using _Ret = decltype(_SourceClock::to_sys(__t));
304 static_assert(__is_time_point_for_v<_Ret, system_clock>);
305 return _SourceClock::to_sys(__t);
309 template<typename _DestClock>
310 struct clock_time_conversion<_DestClock, system_clock>
312 template<typename _Duration, typename _Dest = _DestClock>
314 operator()(const sys_time<_Duration>& __t) const
315 -> decltype(_Dest::from_sys(__t))
317 using _Ret = decltype(_DestClock::from_sys(__t));
318 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
319 return _DestClock::from_sys(__t);
323 // Conversions between utc_clock and other clocks
325 template<typename _SourceClock>
326 struct clock_time_conversion<utc_clock, _SourceClock>
328 template<typename _Duration, typename _Src = _SourceClock>
330 operator()(const time_point<_SourceClock, _Duration>& __t) const
331 -> decltype(_Src::to_utc(__t))
333 using _Ret = decltype(_SourceClock::to_utc(__t));
334 static_assert(__is_time_point_for_v<_Ret, utc_clock>);
335 return _SourceClock::to_utc(__t);
339 template<typename _DestClock>
340 struct clock_time_conversion<_DestClock, utc_clock>
342 template<typename _Duration, typename _Dest = _DestClock>
344 operator()(const utc_time<_Duration>& __t) const
345 -> decltype(_Dest::from_utc(__t))
347 using _Ret = decltype(_DestClock::from_utc(__t));
348 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
349 return _DestClock::from_utc(__t);
353 /// @cond undocumented
356 template<typename _DestClock, typename _SourceClock, typename _Duration>
357 concept __clock_convs
358 = requires (const time_point<_SourceClock, _Duration>& __t) {
359 clock_time_conversion<_DestClock, _SourceClock>{}(__t);
362 template<typename _DestClock, typename _SourceClock, typename _Duration>
363 concept __clock_convs_sys
364 = requires (const time_point<_SourceClock, _Duration>& __t) {
365 clock_time_conversion<_DestClock, system_clock>{}(
366 clock_time_conversion<system_clock, _SourceClock>{}(__t));
369 template<typename _DestClock, typename _SourceClock, typename _Duration>
370 concept __clock_convs_utc
371 = requires (const time_point<_SourceClock, _Duration>& __t) {
372 clock_time_conversion<_DestClock, utc_clock>{}(
373 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
376 template<typename _DestClock, typename _SourceClock, typename _Duration>
377 concept __clock_convs_sys_utc
378 = requires (const time_point<_SourceClock, _Duration>& __t) {
379 clock_time_conversion<_DestClock, utc_clock>{}(
380 clock_time_conversion<utc_clock, system_clock>{}(
381 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
384 template<typename _DestClock, typename _SourceClock, typename _Duration>
385 concept __clock_convs_utc_sys
386 = requires (const time_point<_SourceClock, _Duration>& __t) {
387 clock_time_conversion<_DestClock, system_clock>{}(
388 clock_time_conversion<system_clock, utc_clock>{}(
389 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
392 } // namespace __detail
395 /// Convert a time point to a different clock.
396 template<typename _DestClock, typename _SourceClock, typename _Duration>
398 clock_cast(const time_point<_SourceClock, _Duration>& __t)
399 requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
400 || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
401 || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
402 || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
403 || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
405 constexpr bool __direct
406 = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
407 if constexpr (__direct)
409 return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
413 constexpr bool __convert_via_sys_clock
414 = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
415 constexpr bool __convert_via_utc_clock
416 = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
417 if constexpr (__convert_via_sys_clock)
419 static_assert(!__convert_via_utc_clock,
420 "clock_cast requires a unique best conversion, but "
421 "conversion is possible via system_clock and also via"
423 return clock_time_conversion<_DestClock, system_clock>{}(
424 clock_time_conversion<system_clock, _SourceClock>{}(__t));
426 else if constexpr (__convert_via_utc_clock)
428 return clock_time_conversion<_DestClock, utc_clock>{}(
429 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
433 constexpr bool __convert_via_sys_and_utc_clocks
434 = __detail::__clock_convs_sys_utc<_DestClock,
438 if constexpr (__convert_via_sys_and_utc_clocks)
440 constexpr bool __convert_via_utc_and_sys_clocks
441 = __detail::__clock_convs_utc_sys<_DestClock,
444 static_assert(!__convert_via_utc_and_sys_clocks,
445 "clock_cast requires a unique best conversion, but "
446 "conversion is possible via system_clock followed by "
447 "utc_clock, and also via utc_clock followed by "
449 return clock_time_conversion<_DestClock, utc_clock>{}(
450 clock_time_conversion<utc_clock, system_clock>{}(
451 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
455 return clock_time_conversion<_DestClock, system_clock>{}(
456 clock_time_conversion<system_clock, utc_clock>{}(
457 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
465 // CLASS DECLARATIONS
470 class weekday_indexed;
473 class month_day_last;
475 class month_weekday_last;
477 class year_month_day;
478 class year_month_day_last;
479 class year_month_weekday;
480 class year_month_weekday_last;
484 explicit last_spec() = default;
486 friend constexpr month_day_last
487 operator/(int __m, last_spec) noexcept;
489 friend constexpr month_day_last
490 operator/(last_spec, int __m) noexcept;
493 inline constexpr last_spec last{};
497 // Compute the remainder of the Euclidean division of __n divided by __d.
498 // Euclidean division truncates toward negative infinity and always
499 // produces a remainder in the range of [0,__d-1] (whereas standard
500 // division truncates toward zero and yields a nonpositive remainder
501 // for negative __n).
503 __modulo(long long __n, unsigned __d)
508 return (__d + (__n % __d)) % __d;
511 inline constexpr unsigned __days_per_month[12]
512 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
526 day(unsigned __d) noexcept
531 operator++() noexcept
538 operator++(int) noexcept
546 operator--() noexcept
553 operator--(int) noexcept
561 operator+=(const days& __d) noexcept
568 operator-=(const days& __d) noexcept
575 operator unsigned() const noexcept
580 { return 1 <= _M_d && _M_d <= 31; }
582 friend constexpr bool
583 operator==(const day& __x, const day& __y) noexcept
584 { return unsigned{__x} == unsigned{__y}; }
586 friend constexpr strong_ordering
587 operator<=>(const day& __x, const day& __y) noexcept
588 { return unsigned{__x} <=> unsigned{__y}; }
591 operator+(const day& __x, const days& __y) noexcept
592 { return day(unsigned{__x} + __y.count()); }
595 operator+(const days& __x, const day& __y) noexcept
596 { return __y + __x; }
599 operator-(const day& __x, const days& __y) noexcept
600 { return __x + -__y; }
602 friend constexpr days
603 operator-(const day& __x, const day& __y) noexcept
604 { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
606 friend constexpr month_day
607 operator/(const month& __m, const day& __d) noexcept;
609 friend constexpr month_day
610 operator/(int __m, const day& __d) noexcept;
612 friend constexpr month_day
613 operator/(const day& __d, const month& __m) noexcept;
615 friend constexpr month_day
616 operator/(const day& __d, int __m) noexcept;
618 friend constexpr year_month_day
619 operator/(const year_month& __ym, const day& __d) noexcept;
621 // TODO: Implement operator<<, to_stream, from_stream.
635 month(unsigned __m) noexcept
640 operator++() noexcept
647 operator++(int) noexcept
655 operator--() noexcept
662 operator--(int) noexcept
670 operator+=(const months& __m) noexcept
677 operator-=(const months& __m) noexcept
684 operator unsigned() const noexcept
689 { return 1 <= _M_m && _M_m <= 12; }
691 friend constexpr bool
692 operator==(const month& __x, const month& __y) noexcept
693 { return unsigned{__x} == unsigned{__y}; }
695 friend constexpr strong_ordering
696 operator<=>(const month& __x, const month& __y) noexcept
697 { return unsigned{__x} <=> unsigned{__y}; }
699 friend constexpr month
700 operator+(const month& __x, const months& __y) noexcept
702 auto __n = static_cast<long long>(unsigned{__x}) + (__y.count() - 1);
703 return month{__detail::__modulo(__n, 12) + 1};
706 friend constexpr month
707 operator+(const months& __x, const month& __y) noexcept
708 { return __y + __x; }
710 friend constexpr month
711 operator-(const month& __x, const months& __y) noexcept
712 { return __x + -__y; }
714 friend constexpr months
715 operator-(const month& __x, const month& __y) noexcept
717 const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
718 return months{__dm < 0 ? 12 + __dm : __dm};
721 friend constexpr year_month
722 operator/(const year& __y, const month& __m) noexcept;
724 friend constexpr month_day
725 operator/(const month& __m, int __d) noexcept;
727 friend constexpr month_day_last
728 operator/(const month& __m, last_spec) noexcept;
730 friend constexpr month_day_last
731 operator/(last_spec, const month& __m) noexcept;
733 friend constexpr month_weekday
734 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
736 friend constexpr month_weekday
737 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
739 friend constexpr month_weekday_last
740 operator/(const month& __m, const weekday_last& __wdl) noexcept;
742 friend constexpr month_weekday_last
743 operator/(const weekday_last& __wdl, const month& __m) noexcept;
745 // TODO: Implement operator<<, to_stream, from_stream.
748 inline constexpr month January{1};
749 inline constexpr month February{2};
750 inline constexpr month March{3};
751 inline constexpr month April{4};
752 inline constexpr month May{5};
753 inline constexpr month June{6};
754 inline constexpr month July{7};
755 inline constexpr month August{8};
756 inline constexpr month September{9};
757 inline constexpr month October{10};
758 inline constexpr month November{11};
759 inline constexpr month December{12};
772 year(int __y) noexcept
773 : _M_y{static_cast<short>(__y)}
776 static constexpr year
778 { return year{-32767}; }
780 static constexpr year
782 { return year{32767}; }
785 operator++() noexcept
792 operator++(int) noexcept
800 operator--() noexcept
807 operator--(int) noexcept
815 operator+=(const years& __y) noexcept
822 operator-=(const years& __y) noexcept
829 operator+() const noexcept
833 operator-() const noexcept
834 { return year{-_M_y}; }
837 is_leap() const noexcept
839 // Testing divisibility by 100 first gives better performance, that is,
840 // return (_M_y % 100 != 0 || _M_y % 400 == 0) && _M_y % 4 == 0;
842 // It gets even faster if _M_y is in [-536870800, 536870999]
843 // (which is the case here) and _M_y % 100 is replaced by
844 // __is_multiple_of_100 below.
847 // [1] https://github.com/cassioneri/calendar
848 // [2] https://accu.org/journals/overload/28/155/overload155.pdf#page=16
850 // Furthermore, if y%100 == 0, then y%400==0 is equivalent to y%16==0,
851 // so we can simplify it to (!mult_100 && y % 4 == 0) || y % 16 == 0,
852 // which is equivalent to (y & (mult_100 ? 15 : 3)) == 0.
853 // See https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
855 constexpr uint32_t __multiplier = 42949673;
856 constexpr uint32_t __bound = 42949669;
857 constexpr uint32_t __max_dividend = 1073741799;
858 constexpr uint32_t __offset = __max_dividend / 2 / 100 * 100;
859 const bool __is_multiple_of_100
860 = __multiplier * (_M_y + __offset) < __bound;
861 return (_M_y & (__is_multiple_of_100 ? 15 : 3)) == 0;
865 operator int() const noexcept
870 { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
872 friend constexpr bool
873 operator==(const year& __x, const year& __y) noexcept
874 { return int{__x} == int{__y}; }
876 friend constexpr strong_ordering
877 operator<=>(const year& __x, const year& __y) noexcept
878 { return int{__x} <=> int{__y}; }
880 friend constexpr year
881 operator+(const year& __x, const years& __y) noexcept
882 { return year{int{__x} + static_cast<int>(__y.count())}; }
884 friend constexpr year
885 operator+(const years& __x, const year& __y) noexcept
886 { return __y + __x; }
888 friend constexpr year
889 operator-(const year& __x, const years& __y) noexcept
890 { return __x + -__y; }
892 friend constexpr years
893 operator-(const year& __x, const year& __y) noexcept
894 { return years{int{__x} - int{__y}}; }
896 friend constexpr year_month
897 operator/(const year& __y, int __m) noexcept;
899 friend constexpr year_month_day
900 operator/(const year& __y, const month_day& __md) noexcept;
902 friend constexpr year_month_day
903 operator/(const month_day& __md, const year& __y) noexcept;
905 friend constexpr year_month_day_last
906 operator/(const year& __y, const month_day_last& __mdl) noexcept;
908 friend constexpr year_month_day_last
909 operator/(const month_day_last& __mdl, const year& __y) noexcept;
911 friend constexpr year_month_weekday
912 operator/(const year& __y, const month_weekday& __mwd) noexcept;
914 friend constexpr year_month_weekday
915 operator/(const month_weekday& __mwd, const year& __y) noexcept;
917 friend constexpr year_month_weekday_last
918 operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
920 friend constexpr year_month_weekday_last
921 operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
923 // TODO: Implement operator<<, to_stream, from_stream.
933 static constexpr weekday
934 _S_from_days(const days& __d)
936 auto __n = __d.count();
937 return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);
944 weekday(unsigned __wd) noexcept
945 : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
949 weekday(const sys_days& __dp) noexcept
950 : weekday{_S_from_days(__dp.time_since_epoch())}
954 weekday(const local_days& __dp) noexcept
955 : weekday{sys_days{__dp.time_since_epoch()}}
959 operator++() noexcept
966 operator++(int) noexcept
974 operator--() noexcept
981 operator--(int) noexcept
989 operator+=(const days& __d) noexcept
996 operator-=(const days& __d) noexcept
1003 c_encoding() const noexcept
1007 iso_encoding() const noexcept
1008 { return _M_wd == 0u ? 7u : _M_wd; }
1012 { return _M_wd <= 6; }
1014 constexpr weekday_indexed
1015 operator[](unsigned __index) const noexcept;
1017 constexpr weekday_last
1018 operator[](last_spec) const noexcept;
1020 friend constexpr bool
1021 operator==(const weekday& __x, const weekday& __y) noexcept
1022 { return __x._M_wd == __y._M_wd; }
1024 friend constexpr weekday
1025 operator+(const weekday& __x, const days& __y) noexcept
1027 auto __n = static_cast<long long>(__x._M_wd) + __y.count();
1028 return weekday{__detail::__modulo(__n, 7)};
1031 friend constexpr weekday
1032 operator+(const days& __x, const weekday& __y) noexcept
1033 { return __y + __x; }
1035 friend constexpr weekday
1036 operator-(const weekday& __x, const days& __y) noexcept
1037 { return __x + -__y; }
1039 friend constexpr days
1040 operator-(const weekday& __x, const weekday& __y) noexcept
1042 auto __n = static_cast<long long>(__x._M_wd) - __y._M_wd;
1043 return days{__detail::__modulo(__n, 7)};
1046 // TODO: operator<<, from_stream.
1049 inline constexpr weekday Sunday{0};
1050 inline constexpr weekday Monday{1};
1051 inline constexpr weekday Tuesday{2};
1052 inline constexpr weekday Wednesday{3};
1053 inline constexpr weekday Thursday{4};
1054 inline constexpr weekday Friday{5};
1055 inline constexpr weekday Saturday{6};
1059 class weekday_indexed
1062 chrono::weekday _M_wd;
1063 unsigned char _M_index;
1066 weekday_indexed() = default;
1069 weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1070 : _M_wd(__wd), _M_index(__index)
1073 constexpr chrono::weekday
1074 weekday() const noexcept
1078 index() const noexcept
1079 { return _M_index; };
1083 { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1085 friend constexpr bool
1086 operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
1087 { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
1089 friend constexpr month_weekday
1090 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1092 friend constexpr month_weekday
1093 operator/(int __m, const weekday_indexed& __wdi) noexcept;
1095 friend constexpr month_weekday
1096 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1098 friend constexpr month_weekday
1099 operator/(const weekday_indexed& __wdi, int __m) noexcept;
1101 friend constexpr year_month_weekday
1102 operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1104 // TODO: Implement operator<<.
1107 constexpr weekday_indexed
1108 weekday::operator[](unsigned __index) const noexcept
1109 { return {*this, __index}; }
1116 chrono::weekday _M_wd;
1120 weekday_last(const chrono::weekday& __wd) noexcept
1124 constexpr chrono::weekday
1125 weekday() const noexcept
1130 { return _M_wd.ok(); }
1132 friend constexpr bool
1133 operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1134 { return __x.weekday() == __y.weekday(); }
1136 friend constexpr month_weekday_last
1137 operator/(int __m, const weekday_last& __wdl) noexcept;
1139 friend constexpr month_weekday_last
1140 operator/(const weekday_last& __wdl, int __m) noexcept;
1142 friend constexpr year_month_weekday_last
1143 operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1145 // TODO: Implement operator<<.
1148 constexpr weekday_last
1149 weekday::operator[](last_spec) const noexcept
1150 { return weekday_last{*this}; }
1161 month_day() = default;
1164 month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1165 : _M_m{__m}, _M_d{__d}
1168 constexpr chrono::month
1169 month() const noexcept
1172 constexpr chrono::day
1173 day() const noexcept
1180 && 1u <= unsigned(_M_d)
1181 && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
1184 friend constexpr bool
1185 operator==(const month_day& __x, const month_day& __y) noexcept
1186 { return __x.month() == __y.month() && __x.day() == __y.day(); }
1188 friend constexpr strong_ordering
1189 operator<=>(const month_day& __x, const month_day& __y) noexcept
1192 friend constexpr month_day
1193 operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1194 { return {__m, __d}; }
1196 friend constexpr month_day
1197 operator/(const chrono::month& __m, int __d) noexcept
1198 { return {__m, chrono::day(unsigned(__d))}; }
1200 friend constexpr month_day
1201 operator/(int __m, const chrono::day& __d) noexcept
1202 { return {chrono::month(unsigned(__m)), __d}; }
1204 friend constexpr month_day
1205 operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1206 { return {__m, __d}; }
1208 friend constexpr month_day
1209 operator/(const chrono::day& __d, int __m) noexcept
1210 { return {chrono::month(unsigned(__m)), __d}; }
1212 friend constexpr year_month_day
1213 operator/(int __y, const month_day& __md) noexcept;
1215 friend constexpr year_month_day
1216 operator/(const month_day& __md, int __y) noexcept;
1218 // TODO: Implement operator<<, from_stream.
1223 class month_day_last
1230 month_day_last(const chrono::month& __m) noexcept
1234 constexpr chrono::month
1235 month() const noexcept
1240 { return _M_m.ok(); }
1242 friend constexpr bool
1243 operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1244 { return __x.month() == __y.month(); }
1246 friend constexpr strong_ordering
1247 operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1250 friend constexpr month_day_last
1251 operator/(const chrono::month& __m, last_spec) noexcept
1252 { return month_day_last{__m}; }
1254 friend constexpr month_day_last
1255 operator/(int __m, last_spec) noexcept
1256 { return chrono::month(unsigned(__m)) / last; }
1258 friend constexpr month_day_last
1259 operator/(last_spec, const chrono::month& __m) noexcept
1260 { return __m / last; }
1262 friend constexpr month_day_last
1263 operator/(last_spec, int __m) noexcept
1264 { return __m / last; }
1266 friend constexpr year_month_day_last
1267 operator/(int __y, const month_day_last& __mdl) noexcept;
1269 friend constexpr year_month_day_last
1270 operator/(const month_day_last& __mdl, int __y) noexcept;
1272 // TODO: Implement operator<<.
1281 chrono::weekday_indexed _M_wdi;
1285 month_weekday(const chrono::month& __m,
1286 const chrono::weekday_indexed& __wdi) noexcept
1287 : _M_m{__m}, _M_wdi{__wdi}
1290 constexpr chrono::month
1291 month() const noexcept
1294 constexpr chrono::weekday_indexed
1295 weekday_indexed() const noexcept
1300 { return _M_m.ok() && _M_wdi.ok(); }
1302 friend constexpr bool
1303 operator==(const month_weekday& __x, const month_weekday& __y) noexcept
1305 return __x.month() == __y.month()
1306 && __x.weekday_indexed() == __y.weekday_indexed();
1309 friend constexpr month_weekday
1310 operator/(const chrono::month& __m,
1311 const chrono::weekday_indexed& __wdi) noexcept
1312 { return {__m, __wdi}; }
1314 friend constexpr month_weekday
1315 operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1316 { return chrono::month(unsigned(__m)) / __wdi; }
1318 friend constexpr month_weekday
1319 operator/(const chrono::weekday_indexed& __wdi,
1320 const chrono::month& __m) noexcept
1321 { return __m / __wdi; }
1323 friend constexpr month_weekday
1324 operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1325 { return __m / __wdi; }
1327 friend constexpr year_month_weekday
1328 operator/(int __y, const month_weekday& __mwd) noexcept;
1330 friend constexpr year_month_weekday
1331 operator/(const month_weekday& __mwd, int __y) noexcept;
1333 // TODO: Implement operator<<.
1336 // MONTH_WEEKDAY_LAST
1338 class month_weekday_last
1342 chrono::weekday_last _M_wdl;
1346 month_weekday_last(const chrono::month& __m,
1347 const chrono::weekday_last& __wdl) noexcept
1348 :_M_m{__m}, _M_wdl{__wdl}
1351 constexpr chrono::month
1352 month() const noexcept
1355 constexpr chrono::weekday_last
1356 weekday_last() const noexcept
1361 { return _M_m.ok() && _M_wdl.ok(); }
1363 friend constexpr bool
1364 operator==(const month_weekday_last& __x,
1365 const month_weekday_last& __y) noexcept
1367 return __x.month() == __y.month()
1368 && __x.weekday_last() == __y.weekday_last();
1371 friend constexpr month_weekday_last
1372 operator/(const chrono::month& __m,
1373 const chrono::weekday_last& __wdl) noexcept
1374 { return {__m, __wdl}; }
1376 friend constexpr month_weekday_last
1377 operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1378 { return chrono::month(unsigned(__m)) / __wdl; }
1380 friend constexpr month_weekday_last
1381 operator/(const chrono::weekday_last& __wdl,
1382 const chrono::month& __m) noexcept
1383 { return __m / __wdl; }
1385 friend constexpr month_weekday_last
1386 operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1387 { return chrono::month(unsigned(__m)) / __wdl; }
1389 friend constexpr year_month_weekday_last
1390 operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1392 friend constexpr year_month_weekday_last
1393 operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1395 // TODO: Implement operator<<.
1402 // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1403 // addition/subtraction operator overloads like so:
1405 // Constraints: if the argument supplied by the caller for the months
1406 // parameter is convertible to years, its implicit conversion sequence
1407 // to years is worse than its implicit conversion sequence to months.
1409 // We realize this constraint by templatizing the 'months'-based
1410 // overloads (using a dummy defaulted template parameter), so that
1411 // overload resolution doesn't select the 'months'-based overload unless
1412 // the implicit conversion sequence to 'months' is better than that to
1414 using __months_years_conversion_disambiguator = void;
1424 year_month() = default;
1427 year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1428 : _M_y{__y}, _M_m{__m}
1431 constexpr chrono::year
1432 year() const noexcept
1435 constexpr chrono::month
1436 month() const noexcept
1439 template<typename = __detail::__months_years_conversion_disambiguator>
1440 constexpr year_month&
1441 operator+=(const months& __dm) noexcept
1443 *this = *this + __dm;
1447 template<typename = __detail::__months_years_conversion_disambiguator>
1448 constexpr year_month&
1449 operator-=(const months& __dm) noexcept
1451 *this = *this - __dm;
1455 constexpr year_month&
1456 operator+=(const years& __dy) noexcept
1458 *this = *this + __dy;
1462 constexpr year_month&
1463 operator-=(const years& __dy) noexcept
1465 *this = *this - __dy;
1471 { return _M_y.ok() && _M_m.ok(); }
1473 friend constexpr bool
1474 operator==(const year_month& __x, const year_month& __y) noexcept
1475 { return __x.year() == __y.year() && __x.month() == __y.month(); }
1477 friend constexpr strong_ordering
1478 operator<=>(const year_month& __x, const year_month& __y) noexcept
1481 template<typename = __detail::__months_years_conversion_disambiguator>
1482 friend constexpr year_month
1483 operator+(const year_month& __ym, const months& __dm) noexcept
1486 auto __m = __ym.month() + __dm;
1487 auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1489 ? __ym.year() + years{(__i - 11) / 12}
1490 : __ym.year() + years{__i / 12});
1494 template<typename = __detail::__months_years_conversion_disambiguator>
1495 friend constexpr year_month
1496 operator+(const months& __dm, const year_month& __ym) noexcept
1497 { return __ym + __dm; }
1499 template<typename = __detail::__months_years_conversion_disambiguator>
1500 friend constexpr year_month
1501 operator-(const year_month& __ym, const months& __dm) noexcept
1502 { return __ym + -__dm; }
1504 friend constexpr months
1505 operator-(const year_month& __x, const year_month& __y) noexcept
1507 return (__x.year() - __y.year()
1508 + months{static_cast<int>(unsigned{__x.month()})
1509 - static_cast<int>(unsigned{__y.month()})});
1512 friend constexpr year_month
1513 operator+(const year_month& __ym, const years& __dy) noexcept
1514 { return (__ym.year() + __dy) / __ym.month(); }
1516 friend constexpr year_month
1517 operator+(const years& __dy, const year_month& __ym) noexcept
1518 { return __ym + __dy; }
1520 friend constexpr year_month
1521 operator-(const year_month& __ym, const years& __dy) noexcept
1522 { return __ym + -__dy; }
1524 friend constexpr year_month
1525 operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1526 { return {__y, __m}; }
1528 friend constexpr year_month
1529 operator/(const chrono::year& __y, int __m) noexcept
1530 { return {__y, chrono::month(unsigned(__m))}; }
1532 friend constexpr year_month_day
1533 operator/(const year_month& __ym, int __d) noexcept;
1535 friend constexpr year_month_day_last
1536 operator/(const year_month& __ym, last_spec) noexcept;
1538 // TODO: Implement operator<<, from_stream.
1543 class year_month_day
1550 static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1552 constexpr days _M_days_since_epoch() const noexcept;
1555 year_month_day() = default;
1558 year_month_day(const chrono::year& __y, const chrono::month& __m,
1559 const chrono::day& __d) noexcept
1560 : _M_y{__y}, _M_m{__m}, _M_d{__d}
1564 year_month_day(const year_month_day_last& __ymdl) noexcept;
1567 year_month_day(const sys_days& __dp) noexcept
1568 : year_month_day(_S_from_days(__dp.time_since_epoch()))
1572 year_month_day(const local_days& __dp) noexcept
1573 : year_month_day(sys_days{__dp.time_since_epoch()})
1576 template<typename = __detail::__months_years_conversion_disambiguator>
1577 constexpr year_month_day&
1578 operator+=(const months& __m) noexcept
1580 *this = *this + __m;
1584 template<typename = __detail::__months_years_conversion_disambiguator>
1585 constexpr year_month_day&
1586 operator-=(const months& __m) noexcept
1588 *this = *this - __m;
1592 constexpr year_month_day&
1593 operator+=(const years& __y) noexcept
1595 *this = *this + __y;
1599 constexpr year_month_day&
1600 operator-=(const years& __y) noexcept
1602 *this = *this - __y;
1606 constexpr chrono::year
1607 year() const noexcept
1610 constexpr chrono::month
1611 month() const noexcept
1614 constexpr chrono::day
1615 day() const noexcept
1619 operator sys_days() const noexcept
1620 { return sys_days{_M_days_since_epoch()}; }
1623 operator local_days() const noexcept
1624 { return local_days{sys_days{*this}.time_since_epoch()}; }
1626 constexpr bool ok() const noexcept;
1628 friend constexpr bool
1629 operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1631 return __x.year() == __y.year()
1632 && __x.month() == __y.month()
1633 && __x.day() == __y.day();
1636 friend constexpr strong_ordering
1637 operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1640 template<typename = __detail::__months_years_conversion_disambiguator>
1641 friend constexpr year_month_day
1642 operator+(const year_month_day& __ymd, const months& __dm) noexcept
1643 { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1645 template<typename = __detail::__months_years_conversion_disambiguator>
1646 friend constexpr year_month_day
1647 operator+(const months& __dm, const year_month_day& __ymd) noexcept
1648 { return __ymd + __dm; }
1650 friend constexpr year_month_day
1651 operator+(const year_month_day& __ymd, const years& __dy) noexcept
1652 { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1654 friend constexpr year_month_day
1655 operator+(const years& __dy, const year_month_day& __ymd) noexcept
1656 { return __ymd + __dy; }
1658 template<typename = __detail::__months_years_conversion_disambiguator>
1659 friend constexpr year_month_day
1660 operator-(const year_month_day& __ymd, const months& __dm) noexcept
1661 { return __ymd + -__dm; }
1663 friend constexpr year_month_day
1664 operator-(const year_month_day& __ymd, const years& __dy) noexcept
1665 { return __ymd + -__dy; }
1667 friend constexpr year_month_day
1668 operator/(const year_month& __ym, const chrono::day& __d) noexcept
1669 { return {__ym.year(), __ym.month(), __d}; }
1671 friend constexpr year_month_day
1672 operator/(const year_month& __ym, int __d) noexcept
1673 { return __ym / chrono::day{unsigned(__d)}; }
1675 friend constexpr year_month_day
1676 operator/(const chrono::year& __y, const month_day& __md) noexcept
1677 { return __y / __md.month() / __md.day(); }
1679 friend constexpr year_month_day
1680 operator/(int __y, const month_day& __md) noexcept
1681 { return chrono::year{__y} / __md; }
1683 friend constexpr year_month_day
1684 operator/(const month_day& __md, const chrono::year& __y) noexcept
1685 { return __y / __md; }
1687 friend constexpr year_month_day
1688 operator/(const month_day& __md, int __y) noexcept
1689 { return chrono::year(__y) / __md; }
1691 // TODO: Implement operator<<, from_stream.
1694 // Construct from days since 1970/01/01.
1695 // Proposition 6.3 of Neri and Schneider,
1696 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1697 // https://arxiv.org/abs/2102.06959
1698 constexpr year_month_day
1699 year_month_day::_S_from_days(const days& __dp) noexcept
1701 constexpr auto __z2 = static_cast<uint32_t>(-1468000);
1702 constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1704 const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1706 const auto __n1 = 4 * __r0 + 3;
1707 const auto __q1 = __n1 / 146097;
1708 const auto __r1 = __n1 % 146097 / 4;
1710 constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1711 const auto __n2 = 4 * __r1 + 3;
1712 const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1713 const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1714 const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1716 constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1717 const auto __n3 = 2141 * __r2 + 197913;
1718 const auto __q3 = __n3 / __p16;
1719 const auto __r3 = __n3 % __p16 / 2141;
1721 const auto __y0 = 100 * __q1 + __q2;
1722 const auto __m0 = __q3;
1723 const auto __d0 = __r3;
1725 const auto __j = __r2 >= 306;
1726 const auto __y1 = __y0 + __j;
1727 const auto __m1 = __j ? __m0 - 12 : __m0;
1728 const auto __d1 = __d0 + 1;
1730 return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1731 chrono::month{__m1}, chrono::day{__d1}};
1734 // Days since 1970/01/01.
1735 // Proposition 6.2 of Neri and Schneider,
1736 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1737 // https://arxiv.org/abs/2102.06959
1739 year_month_day::_M_days_since_epoch() const noexcept
1741 auto constexpr __z2 = static_cast<uint32_t>(-1468000);
1742 auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1744 const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1745 const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1746 const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1748 const auto __j = static_cast<uint32_t>(__m1 < 3);
1749 const auto __y0 = __y1 - __j;
1750 const auto __m0 = __j ? __m1 + 12 : __m1;
1751 const auto __d0 = __d1 - 1;
1753 const auto __q1 = __y0 / 100;
1754 const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1755 const auto __mc = (979 *__m0 - 2919) / 32;
1756 const auto __dc = __d0;
1758 return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1761 // YEAR_MONTH_DAY_LAST
1763 class year_month_day_last
1767 chrono::month_day_last _M_mdl;
1771 year_month_day_last(const chrono::year& __y,
1772 const chrono::month_day_last& __mdl) noexcept
1773 : _M_y{__y}, _M_mdl{__mdl}
1776 template<typename = __detail::__months_years_conversion_disambiguator>
1777 constexpr year_month_day_last&
1778 operator+=(const months& __m) noexcept
1780 *this = *this + __m;
1784 template<typename = __detail::__months_years_conversion_disambiguator>
1785 constexpr year_month_day_last&
1786 operator-=(const months& __m) noexcept
1788 *this = *this - __m;
1792 constexpr year_month_day_last&
1793 operator+=(const years& __y) noexcept
1795 *this = *this + __y;
1799 constexpr year_month_day_last&
1800 operator-=(const years& __y) noexcept
1802 *this = *this - __y;
1806 constexpr chrono::year
1807 year() const noexcept
1810 constexpr chrono::month
1811 month() const noexcept
1812 { return _M_mdl.month(); }
1814 constexpr chrono::month_day_last
1815 month_day_last() const noexcept
1818 // Return A day representing the last day of this year, month pair.
1819 constexpr chrono::day
1820 day() const noexcept
1822 const auto __m = static_cast<unsigned>(month());
1824 // Excluding February, the last day of month __m is either 30 or 31 or,
1825 // in another words, it is 30 + b = 30 | b, where b is in {0, 1}.
1827 // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if __m is odd.
1828 // Hence, b = __m & 1 = (__m ^ 0) & 1.
1830 // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if __m is even.
1831 // Hence, b = (__m ^ 1) & 1.
1833 // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1834 // __m >= 8, that is, c = __m >> 3.
1836 // The above mathematically justifies this implementation whose
1837 // performance does not depend on look-up tables being on the L1 cache.
1838 return chrono::day{__m != 2 ? ((__m ^ (__m >> 3)) & 1) | 30
1839 : _M_y.is_leap() ? 29 : 28};
1843 operator sys_days() const noexcept
1844 { return sys_days{year() / month() / day()}; }
1847 operator local_days() const noexcept
1848 { return local_days{sys_days{*this}.time_since_epoch()}; }
1852 { return _M_y.ok() && _M_mdl.ok(); }
1854 friend constexpr bool
1855 operator==(const year_month_day_last& __x,
1856 const year_month_day_last& __y) noexcept
1858 return __x.year() == __y.year()
1859 && __x.month_day_last() == __y.month_day_last();
1862 friend constexpr strong_ordering
1863 operator<=>(const year_month_day_last& __x,
1864 const year_month_day_last& __y) noexcept
1867 template<typename = __detail::__months_years_conversion_disambiguator>
1868 friend constexpr year_month_day_last
1869 operator+(const year_month_day_last& __ymdl,
1870 const months& __dm) noexcept
1871 { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1873 template<typename = __detail::__months_years_conversion_disambiguator>
1874 friend constexpr year_month_day_last
1875 operator+(const months& __dm,
1876 const year_month_day_last& __ymdl) noexcept
1877 { return __ymdl + __dm; }
1879 template<typename = __detail::__months_years_conversion_disambiguator>
1880 friend constexpr year_month_day_last
1881 operator-(const year_month_day_last& __ymdl,
1882 const months& __dm) noexcept
1883 { return __ymdl + -__dm; }
1885 friend constexpr year_month_day_last
1886 operator+(const year_month_day_last& __ymdl,
1887 const years& __dy) noexcept
1888 { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1890 friend constexpr year_month_day_last
1891 operator+(const years& __dy,
1892 const year_month_day_last& __ymdl) noexcept
1893 { return __ymdl + __dy; }
1895 friend constexpr year_month_day_last
1896 operator-(const year_month_day_last& __ymdl,
1897 const years& __dy) noexcept
1898 { return __ymdl + -__dy; }
1900 friend constexpr year_month_day_last
1901 operator/(const year_month& __ym, last_spec) noexcept
1902 { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1904 friend constexpr year_month_day_last
1905 operator/(const chrono::year& __y,
1906 const chrono::month_day_last& __mdl) noexcept
1907 { return {__y, __mdl}; }
1909 friend constexpr year_month_day_last
1910 operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1911 { return chrono::year(__y) / __mdl; }
1913 friend constexpr year_month_day_last
1914 operator/(const chrono::month_day_last& __mdl,
1915 const chrono::year& __y) noexcept
1916 { return __y / __mdl; }
1918 friend constexpr year_month_day_last
1919 operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1920 { return chrono::year(__y) / __mdl; }
1922 // TODO: Implement operator<<.
1925 // year_month_day ctor from year_month_day_last
1927 year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1928 : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1932 year_month_day::ok() const noexcept
1934 if (!_M_y.ok() || !_M_m.ok())
1936 return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1939 // YEAR_MONTH_WEEKDAY
1941 class year_month_weekday
1946 chrono::weekday_indexed _M_wdi;
1948 static constexpr year_month_weekday
1949 _S_from_sys_days(const sys_days& __dp)
1951 year_month_day __ymd{__dp};
1952 chrono::weekday __wd{__dp};
1953 auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1954 return {__ymd.year(), __ymd.month(), __index};
1958 year_month_weekday() = default;
1961 year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1962 const chrono::weekday_indexed& __wdi) noexcept
1963 : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1967 year_month_weekday(const sys_days& __dp) noexcept
1968 : year_month_weekday{_S_from_sys_days(__dp)}
1972 year_month_weekday(const local_days& __dp) noexcept
1973 : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1976 template<typename = __detail::__months_years_conversion_disambiguator>
1977 constexpr year_month_weekday&
1978 operator+=(const months& __m) noexcept
1980 *this = *this + __m;
1984 template<typename = __detail::__months_years_conversion_disambiguator>
1985 constexpr year_month_weekday&
1986 operator-=(const months& __m) noexcept
1988 *this = *this - __m;
1992 constexpr year_month_weekday&
1993 operator+=(const years& __y) noexcept
1995 *this = *this + __y;
1999 constexpr year_month_weekday&
2000 operator-=(const years& __y) noexcept
2002 *this = *this - __y;
2006 constexpr chrono::year
2007 year() const noexcept
2010 constexpr chrono::month
2011 month() const noexcept
2014 constexpr chrono::weekday
2015 weekday() const noexcept
2016 { return _M_wdi.weekday(); }
2019 index() const noexcept
2020 { return _M_wdi.index(); }
2022 constexpr chrono::weekday_indexed
2023 weekday_indexed() const noexcept
2027 operator sys_days() const noexcept
2029 auto __d = sys_days{year() / month() / 1};
2030 return __d + (weekday() - chrono::weekday(__d)
2031 + days{(static_cast<int>(index())-1)*7});
2035 operator local_days() const noexcept
2036 { return local_days{sys_days{*this}.time_since_epoch()}; }
2041 if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
2043 if (_M_wdi.index() <= 4)
2045 days __d = (_M_wdi.weekday()
2046 - chrono::weekday{sys_days{_M_y / _M_m / 1}}
2047 + days((_M_wdi.index()-1)*7 + 1));
2048 __glibcxx_assert(__d.count() >= 1);
2049 return __d.count() <= unsigned{(_M_y / _M_m / last).day()};
2052 friend constexpr bool
2053 operator==(const year_month_weekday& __x,
2054 const year_month_weekday& __y) noexcept
2056 return __x.year() == __y.year()
2057 && __x.month() == __y.month()
2058 && __x.weekday_indexed() == __y.weekday_indexed();
2061 template<typename = __detail::__months_years_conversion_disambiguator>
2062 friend constexpr year_month_weekday
2063 operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
2065 return ((__ymwd.year() / __ymwd.month() + __dm)
2066 / __ymwd.weekday_indexed());
2069 template<typename = __detail::__months_years_conversion_disambiguator>
2070 friend constexpr year_month_weekday
2071 operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
2072 { return __ymwd + __dm; }
2074 friend constexpr year_month_weekday
2075 operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
2076 { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
2078 friend constexpr year_month_weekday
2079 operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2080 { return __ymwd + __dy; }
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 { return __ymwd + -__dm; }
2087 friend constexpr year_month_weekday
2088 operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2089 { return __ymwd + -__dy; }
2091 friend constexpr year_month_weekday
2092 operator/(const year_month& __ym,
2093 const chrono::weekday_indexed& __wdi) noexcept
2094 { return {__ym.year(), __ym.month(), __wdi}; }
2096 friend constexpr year_month_weekday
2097 operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
2098 { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
2100 friend constexpr year_month_weekday
2101 operator/(int __y, const month_weekday& __mwd) noexcept
2102 { return chrono::year(__y) / __mwd; }
2104 friend constexpr year_month_weekday
2105 operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2106 { return __y / __mwd; }
2108 friend constexpr year_month_weekday
2109 operator/(const month_weekday& __mwd, int __y) noexcept
2110 { return chrono::year(__y) / __mwd; }
2112 // TODO: Implement operator<<.
2115 // YEAR_MONTH_WEEKDAY_LAST
2117 class year_month_weekday_last
2122 chrono::weekday_last _M_wdl;
2126 year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
2127 const chrono::weekday_last& __wdl) noexcept
2128 : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
2131 template<typename = __detail::__months_years_conversion_disambiguator>
2132 constexpr year_month_weekday_last&
2133 operator+=(const months& __m) noexcept
2135 *this = *this + __m;
2139 template<typename = __detail::__months_years_conversion_disambiguator>
2140 constexpr year_month_weekday_last&
2141 operator-=(const months& __m) noexcept
2143 *this = *this - __m;
2147 constexpr year_month_weekday_last&
2148 operator+=(const years& __y) noexcept
2150 *this = *this + __y;
2154 constexpr year_month_weekday_last&
2155 operator-=(const years& __y) noexcept
2157 *this = *this - __y;
2161 constexpr chrono::year
2162 year() const noexcept
2165 constexpr chrono::month
2166 month() const noexcept
2169 constexpr chrono::weekday
2170 weekday() const noexcept
2171 { return _M_wdl.weekday(); }
2173 constexpr chrono::weekday_last
2174 weekday_last() const noexcept
2178 operator sys_days() const noexcept
2180 const auto __d = sys_days{_M_y / _M_m / last};
2181 return sys_days{(__d - (chrono::weekday{__d}
2182 - _M_wdl.weekday())).time_since_epoch()};
2186 operator local_days() const noexcept
2187 { return local_days{sys_days{*this}.time_since_epoch()}; }
2191 { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2193 friend constexpr bool
2194 operator==(const year_month_weekday_last& __x,
2195 const year_month_weekday_last& __y) noexcept
2197 return __x.year() == __y.year()
2198 && __x.month() == __y.month()
2199 && __x.weekday_last() == __y.weekday_last();
2202 template<typename = __detail::__months_years_conversion_disambiguator>
2203 friend constexpr year_month_weekday_last
2204 operator+(const year_month_weekday_last& __ymwdl,
2205 const months& __dm) noexcept
2207 return ((__ymwdl.year() / __ymwdl.month() + __dm)
2208 / __ymwdl.weekday_last());
2211 template<typename = __detail::__months_years_conversion_disambiguator>
2212 friend constexpr year_month_weekday_last
2213 operator+(const months& __dm,
2214 const year_month_weekday_last& __ymwdl) noexcept
2215 { return __ymwdl + __dm; }
2217 friend constexpr year_month_weekday_last
2218 operator+(const year_month_weekday_last& __ymwdl,
2219 const years& __dy) noexcept
2220 { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
2222 friend constexpr year_month_weekday_last
2223 operator+(const years& __dy,
2224 const year_month_weekday_last& __ymwdl) noexcept
2225 { return __ymwdl + __dy; }
2227 template<typename = __detail::__months_years_conversion_disambiguator>
2228 friend constexpr year_month_weekday_last
2229 operator-(const year_month_weekday_last& __ymwdl,
2230 const months& __dm) noexcept
2231 { return __ymwdl + -__dm; }
2233 friend constexpr year_month_weekday_last
2234 operator-(const year_month_weekday_last& __ymwdl,
2235 const years& __dy) noexcept
2236 { return __ymwdl + -__dy; }
2238 friend constexpr year_month_weekday_last
2239 operator/(const year_month& __ym,
2240 const chrono::weekday_last& __wdl) noexcept
2241 { return {__ym.year(), __ym.month(), __wdl}; }
2243 friend constexpr year_month_weekday_last
2244 operator/(const chrono::year& __y,
2245 const chrono::month_weekday_last& __mwdl) noexcept
2246 { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
2248 friend constexpr year_month_weekday_last
2249 operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2250 { return chrono::year(__y) / __mwdl; }
2252 friend constexpr year_month_weekday_last
2253 operator/(const chrono::month_weekday_last& __mwdl,
2254 const chrono::year& __y) noexcept
2255 { return __y / __mwdl; }
2257 friend constexpr year_month_weekday_last
2258 operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
2259 { return chrono::year(__y) / __mwdl; }
2261 // TODO: Implement operator<<.
2266 /// @cond undocumented
2270 __pow10(unsigned __n)
2280 /** Utility for splitting a duration into hours, minutes, and seconds
2282 * This is a convenience type that provides accessors for the constituent
2283 * parts (hours, minutes, seconds and subseconds) of a duration.
2287 template<typename _Duration>
2290 static_assert( __is_duration<_Duration>::value );
2293 static consteval int
2294 _S_fractional_width()
2296 auto __den = _Duration::period::den;
2297 const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
2298 __den >>= __multiplicity_2;
2299 int __multiplicity_5 = 0;
2300 while ((__den % 5) == 0)
2308 int __width = (__multiplicity_2 > __multiplicity_5
2309 ? __multiplicity_2 : __multiplicity_5);
2316 hh_mm_ss(_Duration __d, bool __is_neg) noexcept
2317 : _M_h (duration_cast<chrono::hours>(__d)),
2318 _M_m (duration_cast<chrono::minutes>(__d - hours())),
2319 _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
2322 auto __ss = __d - hours() - minutes() - seconds();
2323 if constexpr (treat_as_floating_point_v<typename precision::rep>)
2324 _M_ss._M_r = __ss.count();
2325 else if constexpr (precision::period::den != 1)
2326 _M_ss._M_r = duration_cast<precision>(__ss).count();
2330 static constexpr unsigned fractional_width = {_S_fractional_width()};
2333 = duration<common_type_t<typename _Duration::rep,
2334 chrono::seconds::rep>,
2335 ratio<1, __detail::__pow10(fractional_width)>>;
2337 constexpr hh_mm_ss() noexcept = default;
2340 hh_mm_ss(_Duration __d) noexcept
2341 : hh_mm_ss(chrono::abs(__d), __d < _Duration::zero())
2345 is_negative() const noexcept
2347 if constexpr (!_S_is_unsigned)
2353 constexpr chrono::hours
2354 hours() const noexcept
2357 constexpr chrono::minutes
2358 minutes() const noexcept
2361 constexpr chrono::seconds
2362 seconds() const noexcept
2366 subseconds() const noexcept
2367 { return static_cast<precision>(_M_ss); }
2370 operator precision() const noexcept
2371 { return to_duration(); }
2374 to_duration() const noexcept
2376 if constexpr (!_S_is_unsigned)
2378 return -(_M_h + _M_m + _M_s + subseconds());
2379 return _M_h + _M_m + _M_s + subseconds();
2382 // TODO: Implement operator<<.
2385 static constexpr bool _S_is_unsigned
2386 = __and_v<is_integral<typename _Duration::rep>,
2387 is_unsigned<typename _Duration::rep>>;
2389 template<typename _Ratio>
2390 using __byte_duration = duration<unsigned char, _Ratio>;
2392 // The type of the _M_ss member that holds the subsecond precision.
2393 template<typename _Dur>
2396 typename _Dur::rep _M_r{};
2399 operator _Dur() const noexcept
2400 { return _Dur(_M_r); }
2403 // An empty class if this precision doesn't need subseconds.
2404 template<typename _Rep>
2405 requires (!treat_as_floating_point_v<_Rep>)
2406 struct __subseconds<duration<_Rep, ratio<1>>>
2409 operator duration<_Rep, ratio<1>>() const noexcept
2413 // True if the maximum constructor argument can be represented in _Tp.
2414 template<typename _Tp>
2415 static constexpr bool __fits
2416 = duration_values<typename _Duration::rep>::max()
2417 <= duration_values<_Tp>::max();
2419 template<typename _Rep, typename _Period>
2420 requires (!treat_as_floating_point_v<_Rep>)
2421 && ratio_less_v<_Period, ratio<1, 1>>
2422 && (ratio_greater_equal_v<_Period, ratio<1, 250>>
2423 || __fits<unsigned char>)
2424 struct __subseconds<duration<_Rep, _Period>>
2426 unsigned char _M_r{};
2429 operator duration<_Rep, _Period>() const noexcept
2430 { return duration<_Rep, _Period>(_M_r); }
2433 template<typename _Rep, typename _Period>
2434 requires (!treat_as_floating_point_v<_Rep>)
2435 && ratio_less_v<_Period, ratio<1, 250>>
2436 && (ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
2437 || __fits<uint_least32_t>)
2438 struct __subseconds<duration<_Rep, _Period>>
2440 uint_least32_t _M_r{};
2443 operator duration<_Rep, _Period>() const noexcept
2444 { return duration<_Rep, _Period>(_M_r); }
2447 chrono::hours _M_h{};
2448 __byte_duration<ratio<60>> _M_m{};
2449 __byte_duration<ratio<1>> _M_s{};
2451 __subseconds<precision> _M_ss{};
2454 // 12/24 HOURS FUNCTIONS
2457 is_am(const hours& __h) noexcept
2458 { return 0h <= __h && __h <= 11h; }
2461 is_pm(const hours& __h) noexcept
2462 { return 12h <= __h && __h <= 23h; }
2465 make12(const hours& __h) noexcept
2475 make24(const hours& __h, bool __is_pm) noexcept
2493 // C++20 [time.zones] Time zones
2506 static constexpr int unique = 0;
2507 static constexpr int nonexistent = 1;
2508 static constexpr int ambiguous = 2;
2515 class nonexistent_local_time : public runtime_error
2518 template<typename _Duration>
2519 nonexistent_local_time(const local_time<_Duration>& __tp,
2520 const local_info& __i)
2521 : runtime_error(_S_make_what_str(__tp, __i))
2522 { __glibcxx_assert(__i.result == local_info::nonexistent); }
2525 template<typename _Duration> // TODO
2527 _S_make_what_str(const local_time<_Duration>&, const local_info&);
2530 class ambiguous_local_time : public runtime_error
2533 template<typename _Duration>
2534 ambiguous_local_time(const local_time<_Duration>& __tp,
2535 const local_info& __i)
2536 : runtime_error(_S_make_what_str(__tp, __i))
2537 { __glibcxx_assert(__i.result == local_info::nonexistent); }
2540 template<typename _Duration> // TODO
2542 _S_make_what_str(const local_time<_Duration>&, const local_info&);
2545 enum class choose { earliest, latest };
2550 time_zone(time_zone&&) = default;
2551 time_zone& operator=(time_zone&&) = default;
2553 string_view name() const noexcept { return _M_name; }
2555 template<typename _Duration>
2557 get_info(const sys_time<_Duration>& __st) const;
2559 template<typename _Duration>
2561 get_info(const local_time<_Duration>& __tp) const;
2563 template<typename _Duration>
2564 sys_time<common_type_t<_Duration, seconds>>
2565 to_sys(const local_time<_Duration>& __tp) const;
2567 template<typename _Duration>
2568 sys_time<common_type_t<_Duration, seconds>>
2569 to_sys(const local_time<_Duration>& __tp, choose __z) const;
2571 template<typename _Duration>
2572 local_time<common_type_t<_Duration, seconds>>
2573 to_local(const sys_time<_Duration>& __tp) const;
2576 operator==(const time_zone& __x, const time_zone& __y) noexcept
2577 { return __x.name() == __y.name(); }
2579 friend strong_ordering
2580 operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2581 { return __x.name() <=> __y.name(); }
2586 unique_ptr<_Impl> _M_impl;
2590 const time_zone* locate_zone(string_view __tz_name);
2591 const time_zone* current_zone();
2593 class time_zone_link
2596 time_zone_link(time_zone_link&&) = default;
2597 time_zone_link& operator=(time_zone_link&&) = default;
2599 string_view name() const noexcept { return _M_name; }
2600 string_view target() const noexcept { return _M_target; }
2603 operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2604 { return __x.name() == __y.name(); }
2606 friend strong_ordering
2607 operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2608 { return __x.name() <=> __y.name(); }
2611 friend const tzdb& reload_tzdb();
2612 // TODO unspecified additional constructors
2620 leap_second(const leap_second&) = default;
2621 leap_second& operator=(const leap_second&) = default;
2623 constexpr sys_seconds
2624 date() const noexcept
2626 if (_M_s >= _M_s.zero()) [[likely]]
2627 return sys_seconds(_M_s);
2628 return sys_seconds(-_M_s);
2632 value() const noexcept
2634 if (_M_s >= _M_s.zero()) [[likely]]
2639 // This can be defaulted because the database will never contain two
2640 // leap_second objects with the same date but different signs.
2641 friend constexpr bool
2642 operator==(const leap_second&, const leap_second&) noexcept = default;
2644 friend constexpr strong_ordering
2645 operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2646 { return __x.date() <=> __y.date(); }
2648 template<typename _Duration>
2649 friend constexpr bool
2650 operator==(const leap_second& __x,
2651 const sys_time<_Duration>& __y) noexcept
2652 { return __x.date() == __y; }
2654 template<typename _Duration>
2655 friend constexpr bool
2656 operator<(const leap_second& __x,
2657 const sys_time<_Duration>& __y) noexcept
2658 { return __x.date() < __y; }
2660 template<typename _Duration>
2661 friend constexpr bool
2662 operator<(const sys_time<_Duration>& __x,
2663 const leap_second& __y) noexcept
2664 { return __x < __y.date(); }
2666 template<typename _Duration>
2667 friend constexpr bool
2668 operator>(const leap_second& __x,
2669 const sys_time<_Duration>& __y) noexcept
2670 { return __y < __x.date(); }
2672 template<typename _Duration>
2673 friend constexpr bool
2674 operator>(const sys_time<_Duration>& __x,
2675 const leap_second& __y) noexcept
2676 { return __y.date() < __x; }
2678 template<typename _Duration>
2679 friend constexpr bool
2680 operator<=(const leap_second& __x,
2681 const sys_time<_Duration>& __y) noexcept
2682 { return !(__y < __x.date()); }
2684 template<typename _Duration>
2685 friend constexpr bool
2686 operator<=(const sys_time<_Duration>& __x,
2687 const leap_second& __y) noexcept
2688 { return !(__y.date() < __x); }
2690 template<typename _Duration>
2691 friend constexpr bool
2692 operator>=(const leap_second& __x,
2693 const sys_time<_Duration>& __y) noexcept
2694 { return !(__x.date() < __y); }
2696 template<typename _Duration>
2697 friend constexpr bool
2698 operator>=(const sys_time<_Duration>& __x,
2699 const leap_second& __y) noexcept
2700 { return !(__x < __y.date()); }
2702 template<three_way_comparable_with<seconds> _Duration>
2703 friend constexpr auto
2704 operator<=>(const leap_second& __x,
2705 const sys_time<_Duration>& __y) noexcept
2706 { return __x.date() <=> __y; }
2709 explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2711 friend const tzdb& reload_tzdb();
2712 template<typename _Dur>
2713 friend leap_second_info
2714 get_leap_second_info(const utc_time<_Dur>&);
2716 seconds _M_s; // == date().time_since_epoch() * value().count()
2719 template<class _Tp> struct zoned_traits { };
2722 struct zoned_traits<const time_zone*>
2724 static const time_zone*
2726 { return std::chrono::locate_zone("UTC"); }
2728 static const time_zone*
2729 locate_zone(string_view __name)
2730 { return std::chrono::locate_zone(__name); }
2736 vector<time_zone> zones;
2737 vector<time_zone_link> links;
2738 vector<leap_second> leap_seconds;
2741 locate_zone(string_view __tz_name) const;
2744 current_zone() const;
2747 friend const tzdb& reload_tzdb();
2750 vector<_Rule> _M_rules;
2757 tzdb_list(const tzdb_list&) = delete;
2758 tzdb_list& operator=(const tzdb_list&) = delete;
2760 class const_iterator
2763 using value_type = tzdb;
2764 using reference = const tzdb&;
2765 using pointer = const tzdb*;
2766 using difference_type = ptrdiff_t;
2767 using iterator_category = forward_iterator_tag;
2769 constexpr const_iterator() = default;
2770 const_iterator(const const_iterator&) = default;
2771 const_iterator(const_iterator&&) = default;
2772 const_iterator& operator=(const const_iterator&) = default;
2773 const_iterator& operator=(const_iterator&&) = default;
2775 reference operator*() const noexcept;
2776 pointer operator->() const noexcept { return &**this; }
2777 const_iterator& operator++();
2778 const_iterator operator++(int);
2780 bool operator==(const const_iterator&) const noexcept = default;
2783 explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2785 shared_ptr<_Node> _M_node;
2786 void* _M_reserved = nullptr;
2789 // TODO const tzdb& front() const noexcept;
2791 const_iterator erase_after(const_iterator);
2793 const_iterator begin() const noexcept;
2794 const_iterator end() const noexcept { return {}; }
2795 const_iterator cbegin() const noexcept { return begin(); }
2796 const_iterator cend() const noexcept { return end(); }
2799 constexpr explicit tzdb_list(nullptr_t);
2801 friend const tzdb_list& get_tzdb_list();
2802 friend const tzdb& get_tzdb();
2803 friend const tzdb& reload_tzdb();
2805 static _Node* _S_head;
2806 static shared_ptr<_Node> _S_head_owner;
2810 // const tzdb_list& get_tzdb_list();
2811 // const tzdb& get_tzdb();
2813 // const tzdb& reload_tzdb();
2814 // string remove_version();
2816 template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2817 class zoned_time; // TODO
2819 using zoned_seconds = zoned_time<seconds>;
2821 template<typename _Duration>
2823 get_leap_second_info(const utc_time<_Duration>& __ut)
2825 if constexpr (is_same_v<_Duration, seconds>)
2827 const seconds::rep __leaps[] {
2828 78796800, // 1 Jul 1972
2829 94694400, // 1 Jan 1973
2830 126230400, // 1 Jan 1974
2831 157766400, // 1 Jan 1975
2832 189302400, // 1 Jan 1976
2833 220924800, // 1 Jan 1977
2834 252460800, // 1 Jan 1978
2835 283996800, // 1 Jan 1979
2836 315532800, // 1 Jan 1980
2837 362793600, // 1 Jul 1981
2838 394329600, // 1 Jul 1982
2839 425865600, // 1 Jul 1983
2840 489024000, // 1 Jul 1985
2841 567993600, // 1 Jan 1988
2842 631152000, // 1 Jan 1990
2843 662688000, // 1 Jan 1991
2844 709948800, // 1 Jul 1992
2845 741484800, // 1 Jul 1993
2846 773020800, // 1 Jul 1994
2847 820454400, // 1 Jan 1996
2848 867715200, // 1 Jul 1997
2849 915148800, // 1 Jan 1999
2850 1136073600, // 1 Jan 2006
2851 1230768000, // 1 Jan 2009
2852 1341100800, // 1 Jul 2012
2853 1435708800, // 1 Jul 2015
2854 1483228800, // 1 Jan 2017
2856 // The list above is known to be valid until 2023-06-28 00:00:00 UTC
2857 const seconds::rep __expires = 1687910400;
2858 const seconds::rep __s = __ut.time_since_epoch().count();
2860 const seconds::rep* __first = std::begin(__leaps);
2861 const seconds::rep* __last = std::end(__leaps);
2863 if (__s > __expires)
2865 // TODO: use updated leap_seconds from tzdb
2867 auto __db = get_tzdb_list().begin();
2868 __first = __db->leap_seconds.data();
2869 __last = __first + __db->leap_seconds.size();
2873 // Don't bother searching the list if we're after the last one.
2874 if (__s > __last[-1])
2875 return { false, seconds(__last - __first) };
2877 auto __pos = std::upper_bound(__first, __last, __s);
2879 __pos != begin(__leaps) && __pos[-1] == __s,
2880 seconds{__pos - __first}
2885 auto __s = chrono::time_point_cast<seconds>(__ut);
2886 return chrono::get_leap_second_info(__s);
2892 } // namespace chrono
2894 #if __cplusplus >= 202002L
2895 inline namespace literals
2897 inline namespace chrono_literals
2899 /// @addtogroup chrono
2901 #pragma GCC diagnostic push
2902 #pragma GCC diagnostic ignored "-Wliteral-suffix"
2903 /// Literal suffix for creating chrono::day objects.
2905 constexpr chrono::day
2906 operator""d(unsigned long long __d) noexcept
2907 { return chrono::day{static_cast<unsigned>(__d)}; }
2909 /// Literal suffix for creating chrono::year objects.
2911 constexpr chrono::year
2912 operator""y(unsigned long long __y) noexcept
2913 { return chrono::year{static_cast<int>(__y)}; }
2914 #pragma GCC diagnostic pop
2916 } // inline namespace chrono_literals
2917 } // inline namespace literals
2921 /// @addtogroup chrono
2924 /// @cond undocumented
2927 template<typename _Period>
2929 __units_suffix_misc(char* __buf, size_t __n) noexcept
2931 namespace __tc = std::__detail;
2934 unsigned __nlen = __tc::__to_chars_len((uintmax_t)_Period::num);
2935 __tc::__to_chars_10_impl(__p + 1, __nlen, (uintmax_t)_Period::num);
2937 if constexpr (_Period::den != 1)
2940 unsigned __dlen = __tc::__to_chars_len((uintmax_t)_Period::den);
2941 __tc::__to_chars_10_impl(__p + 1, __dlen, (uintmax_t)_Period::den);
2950 template<typename _Period, typename _CharT>
2952 __units_suffix(char* __buf, size_t __n) noexcept
2954 #define _GLIBCXX_UNITS_SUFFIX(period, suffix) \
2955 if constexpr (is_same_v<_Period, period>) \
2957 if constexpr (is_same_v<_CharT, wchar_t>) \
2964 _GLIBCXX_UNITS_SUFFIX(atto, "as")
2965 _GLIBCXX_UNITS_SUFFIX(femto, "fs")
2966 _GLIBCXX_UNITS_SUFFIX(pico, "ps")
2967 _GLIBCXX_UNITS_SUFFIX(nano, "ns")
2968 _GLIBCXX_UNITS_SUFFIX(micro, "\u00b5s")
2969 _GLIBCXX_UNITS_SUFFIX(milli, "ms")
2970 _GLIBCXX_UNITS_SUFFIX(centi, "cs")
2971 _GLIBCXX_UNITS_SUFFIX(deci, "ds")
2972 _GLIBCXX_UNITS_SUFFIX(ratio<1>, "s")
2973 _GLIBCXX_UNITS_SUFFIX(deca, "das")
2974 _GLIBCXX_UNITS_SUFFIX(hecto, "hs")
2975 _GLIBCXX_UNITS_SUFFIX(kilo, "ks")
2976 _GLIBCXX_UNITS_SUFFIX(mega, "Ms")
2977 _GLIBCXX_UNITS_SUFFIX(giga, "Gs")
2978 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2979 _GLIBCXX_UNITS_SUFFIX(tera, "Ts")
2980 _GLIBCXX_UNITS_SUFFIX(peta, "Ps")
2981 _GLIBCXX_UNITS_SUFFIX(exa, "Es")
2982 _GLIBCXX_UNITS_SUFFIX(ratio<60>, "min")
2983 _GLIBCXX_UNITS_SUFFIX(ratio<3600>, "h")
2984 _GLIBCXX_UNITS_SUFFIX(ratio<86400>, "d")
2985 #undef _GLIBCXX_UNITS_SUFFIX
2986 return __detail::__units_suffix_misc<_Period>(__buf, __n);
2988 } // namespace __detail
2991 template<typename _CharT, typename _Traits,
2992 typename _Rep, typename _Period>
2993 inline basic_ostream<_CharT, _Traits>&
2994 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
2995 const duration<_Rep, _Period>& __d)
2997 using period = typename _Period::type;
2998 char __buf[sizeof("[/]s") + 2 * numeric_limits<intmax_t>::digits10];
2999 std::basic_ostringstream<_CharT, _Traits> __s;
3000 __s.flags(__os.flags());
3001 __s.imbue(__os.getloc());
3002 __s.precision(__os.precision());
3004 __s << __detail::__units_suffix<period, _CharT>(__buf, sizeof(__buf));
3005 __os << std::move(__s).str();
3009 // TODO: from_stream for duration
3012 } // namespace chrono
3015 _GLIBCXX_END_NAMESPACE_VERSION
3020 #endif //_GLIBCXX_CHRONO