1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008-2023 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/stl_algo.h> // upper_bound
49 # include <bits/shared_ptr.h>
50 # include <bits/unique_ptr.h>
53 namespace std _GLIBCXX_VISIBILITY(default)
55 _GLIBCXX_BEGIN_NAMESPACE_VERSION
58 * @defgroup chrono Time
61 * Classes and functions for time.
66 /** @namespace std::chrono
67 * @brief ISO C++ 2011 namespace for date and time utilities
72 #if __cplusplus >= 202002L
73 /// @addtogroup chrono
76 template<typename _Duration>
77 using local_time = time_point<local_t, _Duration>;
78 using local_seconds = local_time<seconds>;
79 using local_days = local_time<days>;
85 template<typename _Duration>
86 using utc_time = time_point<utc_clock, _Duration>;
87 using utc_seconds = utc_time<seconds>;
89 template<typename _Duration>
90 using tai_time = time_point<tai_clock, _Duration>;
91 using tai_seconds = tai_time<seconds>;
93 template<typename _Duration>
94 using gps_time = time_point<gps_clock, _Duration>;
95 using gps_seconds = gps_time<seconds>;
97 template<> struct is_clock<utc_clock> : true_type { };
98 template<> struct is_clock<tai_clock> : true_type { };
99 template<> struct is_clock<gps_clock> : true_type { };
101 template<> inline constexpr bool is_clock_v<utc_clock> = true;
102 template<> inline constexpr bool is_clock_v<tai_clock> = true;
103 template<> inline constexpr bool is_clock_v<gps_clock> = true;
105 struct leap_second_info
111 template<typename _Duration>
113 get_leap_second_info(const utc_time<_Duration>& __ut);
115 /** A clock that measures Universal Coordinated Time (UTC).
117 * The epoch is 1970-01-01 00:00:00.
124 using rep = system_clock::rep;
125 using period = system_clock::period;
126 using duration = chrono::duration<rep, period>;
127 using time_point = chrono::time_point<utc_clock>;
128 static constexpr bool is_steady = false;
133 { return from_sys(system_clock::now()); }
135 template<typename _Duration>
137 static sys_time<common_type_t<_Duration, seconds>>
138 to_sys(const utc_time<_Duration>& __t)
140 using _CDur = common_type_t<_Duration, seconds>;
141 const auto __li = chrono::get_leap_second_info(__t);
142 sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
143 if (__li.is_leap_second)
144 __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
148 template<typename _Duration>
150 static utc_time<common_type_t<_Duration, seconds>>
151 from_sys(const sys_time<_Duration>& __t);
154 /** A clock that measures International Atomic Time.
156 * The epoch is 1958-01-01 00:00:00.
163 using rep = system_clock::rep;
164 using period = system_clock::period;
165 using duration = chrono::duration<rep, period>;
166 using time_point = chrono::time_point<tai_clock>;
167 static constexpr bool is_steady = false; // XXX true for CLOCK_TAI?
169 // TODO move into lib, use CLOCK_TAI on linux, add extension point.
173 { return from_utc(utc_clock::now()); }
175 template<typename _Duration>
177 static utc_time<common_type_t<_Duration, seconds>>
178 to_utc(const tai_time<_Duration>& __t)
180 using _CDur = common_type_t<_Duration, seconds>;
181 return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
184 template<typename _Duration>
186 static tai_time<common_type_t<_Duration, seconds>>
187 from_utc(const utc_time<_Duration>& __t)
189 using _CDur = common_type_t<_Duration, seconds>;
190 return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
194 /** A clock that measures GPS time.
196 * The epoch is 1980-01-06 00:00:00.
203 using rep = system_clock::rep;
204 using period = system_clock::period;
205 using duration = chrono::duration<rep, period>;
206 using time_point = chrono::time_point<gps_clock>;
207 static constexpr bool is_steady = false; // XXX
209 // TODO move into lib, add extension point.
213 { return from_utc(utc_clock::now()); }
215 template<typename _Duration>
217 static utc_time<common_type_t<_Duration, seconds>>
218 to_utc(const gps_time<_Duration>& __t)
220 using _CDur = common_type_t<_Duration, seconds>;
221 return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
224 template<typename _Duration>
226 static gps_time<common_type_t<_Duration, seconds>>
227 from_utc(const utc_time<_Duration>& __t)
229 using _CDur = common_type_t<_Duration, seconds>;
230 return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
235 template<typename _DestClock, typename _SourceClock>
236 struct clock_time_conversion
239 // Identity conversions
241 template<typename _Clock>
242 struct clock_time_conversion<_Clock, _Clock>
244 template<typename _Duration>
245 time_point<_Clock, _Duration>
246 operator()(const time_point<_Clock, _Duration>& __t) const
251 struct clock_time_conversion<system_clock, system_clock>
253 template<typename _Duration>
255 operator()(const sys_time<_Duration>& __t) const
260 struct clock_time_conversion<utc_clock, utc_clock>
262 template<typename _Duration>
264 operator()(const utc_time<_Duration>& __t) const
268 // Conversions between system_clock and utc_clock
271 struct clock_time_conversion<utc_clock, system_clock>
273 template<typename _Duration>
274 utc_time<common_type_t<_Duration, seconds>>
275 operator()(const sys_time<_Duration>& __t) const
276 { return utc_clock::from_sys(__t); }
280 struct clock_time_conversion<system_clock, utc_clock>
282 template<typename _Duration>
283 sys_time<common_type_t<_Duration, seconds>>
284 operator()(const utc_time<_Duration>& __t) const
285 { return utc_clock::to_sys(__t); }
288 template<typename _Tp, typename _Clock>
289 inline constexpr bool __is_time_point_for_v = false;
291 template<typename _Clock, typename _Duration>
292 inline constexpr bool
293 __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
295 // Conversions between system_clock and other clocks
297 template<typename _SourceClock>
298 struct clock_time_conversion<system_clock, _SourceClock>
300 template<typename _Duration, typename _Src = _SourceClock>
302 operator()(const time_point<_SourceClock, _Duration>& __t) const
303 -> decltype(_Src::to_sys(__t))
305 using _Ret = decltype(_SourceClock::to_sys(__t));
306 static_assert(__is_time_point_for_v<_Ret, system_clock>);
307 return _SourceClock::to_sys(__t);
311 template<typename _DestClock>
312 struct clock_time_conversion<_DestClock, system_clock>
314 template<typename _Duration, typename _Dest = _DestClock>
316 operator()(const sys_time<_Duration>& __t) const
317 -> decltype(_Dest::from_sys(__t))
319 using _Ret = decltype(_DestClock::from_sys(__t));
320 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
321 return _DestClock::from_sys(__t);
325 // Conversions between utc_clock and other clocks
327 template<typename _SourceClock>
328 struct clock_time_conversion<utc_clock, _SourceClock>
330 template<typename _Duration, typename _Src = _SourceClock>
332 operator()(const time_point<_SourceClock, _Duration>& __t) const
333 -> decltype(_Src::to_utc(__t))
335 using _Ret = decltype(_SourceClock::to_utc(__t));
336 static_assert(__is_time_point_for_v<_Ret, utc_clock>);
337 return _SourceClock::to_utc(__t);
341 template<typename _DestClock>
342 struct clock_time_conversion<_DestClock, utc_clock>
344 template<typename _Duration, typename _Dest = _DestClock>
346 operator()(const utc_time<_Duration>& __t) const
347 -> decltype(_Dest::from_utc(__t))
349 using _Ret = decltype(_DestClock::from_utc(__t));
350 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
351 return _DestClock::from_utc(__t);
355 /// @cond undocumented
358 template<typename _DestClock, typename _SourceClock, typename _Duration>
359 concept __clock_convs
360 = requires (const time_point<_SourceClock, _Duration>& __t) {
361 clock_time_conversion<_DestClock, _SourceClock>{}(__t);
364 template<typename _DestClock, typename _SourceClock, typename _Duration>
365 concept __clock_convs_sys
366 = requires (const time_point<_SourceClock, _Duration>& __t) {
367 clock_time_conversion<_DestClock, system_clock>{}(
368 clock_time_conversion<system_clock, _SourceClock>{}(__t));
371 template<typename _DestClock, typename _SourceClock, typename _Duration>
372 concept __clock_convs_utc
373 = requires (const time_point<_SourceClock, _Duration>& __t) {
374 clock_time_conversion<_DestClock, utc_clock>{}(
375 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
378 template<typename _DestClock, typename _SourceClock, typename _Duration>
379 concept __clock_convs_sys_utc
380 = requires (const time_point<_SourceClock, _Duration>& __t) {
381 clock_time_conversion<_DestClock, utc_clock>{}(
382 clock_time_conversion<utc_clock, system_clock>{}(
383 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
386 template<typename _DestClock, typename _SourceClock, typename _Duration>
387 concept __clock_convs_utc_sys
388 = requires (const time_point<_SourceClock, _Duration>& __t) {
389 clock_time_conversion<_DestClock, system_clock>{}(
390 clock_time_conversion<system_clock, utc_clock>{}(
391 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
394 } // namespace __detail
397 /// Convert a time point to a different clock.
398 template<typename _DestClock, typename _SourceClock, typename _Duration>
401 clock_cast(const time_point<_SourceClock, _Duration>& __t)
402 requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
403 || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
404 || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
405 || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
406 || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
408 constexpr bool __direct
409 = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
410 if constexpr (__direct)
412 return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
416 constexpr bool __convert_via_sys_clock
417 = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
418 constexpr bool __convert_via_utc_clock
419 = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
420 if constexpr (__convert_via_sys_clock)
422 static_assert(!__convert_via_utc_clock,
423 "clock_cast requires a unique best conversion, but "
424 "conversion is possible via system_clock and also via"
426 return clock_time_conversion<_DestClock, system_clock>{}(
427 clock_time_conversion<system_clock, _SourceClock>{}(__t));
429 else if constexpr (__convert_via_utc_clock)
431 return clock_time_conversion<_DestClock, utc_clock>{}(
432 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
436 constexpr bool __convert_via_sys_and_utc_clocks
437 = __detail::__clock_convs_sys_utc<_DestClock,
441 if constexpr (__convert_via_sys_and_utc_clocks)
443 constexpr bool __convert_via_utc_and_sys_clocks
444 = __detail::__clock_convs_utc_sys<_DestClock,
447 static_assert(!__convert_via_utc_and_sys_clocks,
448 "clock_cast requires a unique best conversion, but "
449 "conversion is possible via system_clock followed by "
450 "utc_clock, and also via utc_clock followed by "
452 return clock_time_conversion<_DestClock, utc_clock>{}(
453 clock_time_conversion<utc_clock, system_clock>{}(
454 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
458 return clock_time_conversion<_DestClock, system_clock>{}(
459 clock_time_conversion<system_clock, utc_clock>{}(
460 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
468 // CLASS DECLARATIONS
473 class weekday_indexed;
476 class month_day_last;
478 class month_weekday_last;
480 class year_month_day;
481 class year_month_day_last;
482 class year_month_weekday;
483 class year_month_weekday_last;
487 explicit last_spec() = default;
489 friend constexpr month_day_last
490 operator/(int __m, last_spec) noexcept;
492 friend constexpr month_day_last
493 operator/(last_spec, int __m) noexcept;
496 inline constexpr last_spec last{};
500 // Compute the remainder of the Euclidean division of __n divided by __d.
501 // Euclidean division truncates toward negative infinity and always
502 // produces a remainder in the range of [0,__d-1] (whereas standard
503 // division truncates toward zero and yields a nonpositive remainder
504 // for negative __n).
506 __modulo(long long __n, unsigned __d)
511 return (__d + (__n % __d)) % __d;
514 inline constexpr unsigned __days_per_month[12]
515 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
529 day(unsigned __d) noexcept
534 operator++() noexcept
541 operator++(int) noexcept
549 operator--() noexcept
556 operator--(int) noexcept
564 operator+=(const days& __d) noexcept
571 operator-=(const days& __d) noexcept
578 operator unsigned() const noexcept
583 { return 1 <= _M_d && _M_d <= 31; }
585 friend constexpr bool
586 operator==(const day& __x, const day& __y) noexcept
587 { return unsigned{__x} == unsigned{__y}; }
589 friend constexpr strong_ordering
590 operator<=>(const day& __x, const day& __y) noexcept
591 { return unsigned{__x} <=> unsigned{__y}; }
594 operator+(const day& __x, const days& __y) noexcept
595 { return day(unsigned{__x} + __y.count()); }
598 operator+(const days& __x, const day& __y) noexcept
599 { return __y + __x; }
602 operator-(const day& __x, const days& __y) noexcept
603 { return __x + -__y; }
605 friend constexpr days
606 operator-(const day& __x, const day& __y) noexcept
607 { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
609 friend constexpr month_day
610 operator/(const month& __m, const day& __d) noexcept;
612 friend constexpr month_day
613 operator/(int __m, const day& __d) noexcept;
615 friend constexpr month_day
616 operator/(const day& __d, const month& __m) noexcept;
618 friend constexpr month_day
619 operator/(const day& __d, int __m) noexcept;
621 friend constexpr year_month_day
622 operator/(const year_month& __ym, const day& __d) noexcept;
636 month(unsigned __m) noexcept
641 operator++() noexcept
648 operator++(int) noexcept
656 operator--() noexcept
663 operator--(int) noexcept
671 operator+=(const months& __m) noexcept
678 operator-=(const months& __m) noexcept
685 operator unsigned() const noexcept
690 { return 1 <= _M_m && _M_m <= 12; }
692 friend constexpr bool
693 operator==(const month& __x, const month& __y) noexcept
694 { return unsigned{__x} == unsigned{__y}; }
696 friend constexpr strong_ordering
697 operator<=>(const month& __x, const month& __y) noexcept
698 { return unsigned{__x} <=> unsigned{__y}; }
700 friend constexpr month
701 operator+(const month& __x, const months& __y) noexcept
703 auto __n = static_cast<long long>(unsigned{__x}) + (__y.count() - 1);
704 return month{__detail::__modulo(__n, 12) + 1};
707 friend constexpr month
708 operator+(const months& __x, const month& __y) noexcept
709 { return __y + __x; }
711 friend constexpr month
712 operator-(const month& __x, const months& __y) noexcept
713 { return __x + -__y; }
715 friend constexpr months
716 operator-(const month& __x, const month& __y) noexcept
718 const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
719 return months{__dm < 0 ? 12 + __dm : __dm};
722 friend constexpr year_month
723 operator/(const year& __y, const month& __m) noexcept;
725 friend constexpr month_day
726 operator/(const month& __m, int __d) noexcept;
728 friend constexpr month_day_last
729 operator/(const month& __m, last_spec) noexcept;
731 friend constexpr month_day_last
732 operator/(last_spec, const month& __m) noexcept;
734 friend constexpr month_weekday
735 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
737 friend constexpr month_weekday
738 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
740 friend constexpr month_weekday_last
741 operator/(const month& __m, const weekday_last& __wdl) noexcept;
743 friend constexpr month_weekday_last
744 operator/(const weekday_last& __wdl, const month& __m) noexcept;
747 inline constexpr month January{1};
748 inline constexpr month February{2};
749 inline constexpr month March{3};
750 inline constexpr month April{4};
751 inline constexpr month May{5};
752 inline constexpr month June{6};
753 inline constexpr month July{7};
754 inline constexpr month August{8};
755 inline constexpr month September{9};
756 inline constexpr month October{10};
757 inline constexpr month November{11};
758 inline constexpr month December{12};
771 year(int __y) noexcept
772 : _M_y{static_cast<short>(__y)}
775 static constexpr year
777 { return year{-32767}; }
779 static constexpr year
781 { return year{32767}; }
784 operator++() noexcept
791 operator++(int) noexcept
799 operator--() noexcept
806 operator--(int) noexcept
814 operator+=(const years& __y) noexcept
821 operator-=(const years& __y) noexcept
828 operator+() const noexcept
832 operator-() const noexcept
833 { return year{-_M_y}; }
836 is_leap() const noexcept
838 // Testing divisibility by 100 first gives better performance [1], i.e.,
839 // return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
840 // Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
841 // to _M_y % 16 == 0, so we can simplify it to
842 // return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #1
843 // Similarly, we can replace 100 with 25 (which is good since
844 // _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
846 // return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #2
847 // Indeed, first assume _M_y % 4 != 0. Then _M_y % 16 != 0 and hence,
848 // _M_y % 4 == 0 and _M_y % 16 == 0 are both false. Therefore, #2
849 // returns false as it should (regardless of _M_y % 25.) Now assume
850 // _M_y % 4 == 0. In this case, _M_y % 25 == 0 if, and only if,
851 // _M_y % 100 == 0, that is, #1 and #2 are equivalent. Finally, #2 is
853 // return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
856 // [1] https://github.com/cassioneri/calendar
857 // [2] https://godbolt.org/z/55G8rn77e
858 // [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
860 return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
864 operator int() const noexcept
869 { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
871 friend constexpr bool
872 operator==(const year& __x, const year& __y) noexcept
873 { return int{__x} == int{__y}; }
875 friend constexpr strong_ordering
876 operator<=>(const year& __x, const year& __y) noexcept
877 { return int{__x} <=> int{__y}; }
879 friend constexpr year
880 operator+(const year& __x, const years& __y) noexcept
881 { return year{int{__x} + static_cast<int>(__y.count())}; }
883 friend constexpr year
884 operator+(const years& __x, const year& __y) noexcept
885 { return __y + __x; }
887 friend constexpr year
888 operator-(const year& __x, const years& __y) noexcept
889 { return __x + -__y; }
891 friend constexpr years
892 operator-(const year& __x, const year& __y) noexcept
893 { return years{int{__x} - int{__y}}; }
895 friend constexpr year_month
896 operator/(const year& __y, int __m) noexcept;
898 friend constexpr year_month_day
899 operator/(const year& __y, const month_day& __md) noexcept;
901 friend constexpr year_month_day
902 operator/(const month_day& __md, const year& __y) noexcept;
904 friend constexpr year_month_day_last
905 operator/(const year& __y, const month_day_last& __mdl) noexcept;
907 friend constexpr year_month_day_last
908 operator/(const month_day_last& __mdl, const year& __y) noexcept;
910 friend constexpr year_month_weekday
911 operator/(const year& __y, const month_weekday& __mwd) noexcept;
913 friend constexpr year_month_weekday
914 operator/(const month_weekday& __mwd, const year& __y) noexcept;
916 friend constexpr year_month_weekday_last
917 operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
919 friend constexpr year_month_weekday_last
920 operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
930 static constexpr weekday
931 _S_from_days(const days& __d)
933 auto __n = __d.count();
934 return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);
941 weekday(unsigned __wd) noexcept
942 : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
946 weekday(const sys_days& __dp) noexcept
947 : weekday{_S_from_days(__dp.time_since_epoch())}
951 weekday(const local_days& __dp) noexcept
952 : weekday{sys_days{__dp.time_since_epoch()}}
956 operator++() noexcept
963 operator++(int) noexcept
971 operator--() noexcept
978 operator--(int) noexcept
986 operator+=(const days& __d) noexcept
993 operator-=(const days& __d) noexcept
1000 c_encoding() const noexcept
1004 iso_encoding() const noexcept
1005 { return _M_wd == 0u ? 7u : _M_wd; }
1009 { return _M_wd <= 6; }
1011 constexpr weekday_indexed
1012 operator[](unsigned __index) const noexcept;
1014 constexpr weekday_last
1015 operator[](last_spec) const noexcept;
1017 friend constexpr bool
1018 operator==(const weekday& __x, const weekday& __y) noexcept
1019 { return __x._M_wd == __y._M_wd; }
1021 friend constexpr weekday
1022 operator+(const weekday& __x, const days& __y) noexcept
1024 auto __n = static_cast<long long>(__x._M_wd) + __y.count();
1025 return weekday{__detail::__modulo(__n, 7)};
1028 friend constexpr weekday
1029 operator+(const days& __x, const weekday& __y) noexcept
1030 { return __y + __x; }
1032 friend constexpr weekday
1033 operator-(const weekday& __x, const days& __y) noexcept
1034 { return __x + -__y; }
1036 friend constexpr days
1037 operator-(const weekday& __x, const weekday& __y) noexcept
1039 auto __n = static_cast<long long>(__x._M_wd) - __y._M_wd;
1040 return days{__detail::__modulo(__n, 7)};
1044 inline constexpr weekday Sunday{0};
1045 inline constexpr weekday Monday{1};
1046 inline constexpr weekday Tuesday{2};
1047 inline constexpr weekday Wednesday{3};
1048 inline constexpr weekday Thursday{4};
1049 inline constexpr weekday Friday{5};
1050 inline constexpr weekday Saturday{6};
1054 class weekday_indexed
1057 chrono::weekday _M_wd;
1058 unsigned char _M_index;
1061 weekday_indexed() = default;
1064 weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1065 : _M_wd(__wd), _M_index(__index)
1068 constexpr chrono::weekday
1069 weekday() const noexcept
1073 index() const noexcept
1074 { return _M_index; };
1078 { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1080 friend constexpr bool
1081 operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
1082 { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
1084 friend constexpr month_weekday
1085 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1087 friend constexpr month_weekday
1088 operator/(int __m, const weekday_indexed& __wdi) noexcept;
1090 friend constexpr month_weekday
1091 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1093 friend constexpr month_weekday
1094 operator/(const weekday_indexed& __wdi, int __m) noexcept;
1096 friend constexpr year_month_weekday
1097 operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1100 constexpr weekday_indexed
1101 weekday::operator[](unsigned __index) const noexcept
1102 { return {*this, __index}; }
1109 chrono::weekday _M_wd;
1113 weekday_last(const chrono::weekday& __wd) noexcept
1117 constexpr chrono::weekday
1118 weekday() const noexcept
1123 { return _M_wd.ok(); }
1125 friend constexpr bool
1126 operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1127 { return __x.weekday() == __y.weekday(); }
1129 friend constexpr month_weekday_last
1130 operator/(int __m, const weekday_last& __wdl) noexcept;
1132 friend constexpr month_weekday_last
1133 operator/(const weekday_last& __wdl, int __m) noexcept;
1135 friend constexpr year_month_weekday_last
1136 operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1139 constexpr weekday_last
1140 weekday::operator[](last_spec) const noexcept
1141 { return weekday_last{*this}; }
1152 month_day() = default;
1155 month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1156 : _M_m{__m}, _M_d{__d}
1159 constexpr chrono::month
1160 month() const noexcept
1163 constexpr chrono::day
1164 day() const noexcept
1171 && 1u <= unsigned(_M_d)
1172 && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
1175 friend constexpr bool
1176 operator==(const month_day& __x, const month_day& __y) noexcept
1177 { return __x.month() == __y.month() && __x.day() == __y.day(); }
1179 friend constexpr strong_ordering
1180 operator<=>(const month_day& __x, const month_day& __y) noexcept
1183 friend constexpr month_day
1184 operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1185 { return {__m, __d}; }
1187 friend constexpr month_day
1188 operator/(const chrono::month& __m, int __d) noexcept
1189 { return {__m, chrono::day(unsigned(__d))}; }
1191 friend constexpr month_day
1192 operator/(int __m, const chrono::day& __d) noexcept
1193 { return {chrono::month(unsigned(__m)), __d}; }
1195 friend constexpr month_day
1196 operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1197 { return {__m, __d}; }
1199 friend constexpr month_day
1200 operator/(const chrono::day& __d, int __m) noexcept
1201 { return {chrono::month(unsigned(__m)), __d}; }
1203 friend constexpr year_month_day
1204 operator/(int __y, const month_day& __md) noexcept;
1206 friend constexpr year_month_day
1207 operator/(const month_day& __md, int __y) noexcept;
1212 class month_day_last
1219 month_day_last(const chrono::month& __m) noexcept
1223 constexpr chrono::month
1224 month() const noexcept
1229 { return _M_m.ok(); }
1231 friend constexpr bool
1232 operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1233 { return __x.month() == __y.month(); }
1235 friend constexpr strong_ordering
1236 operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1239 friend constexpr month_day_last
1240 operator/(const chrono::month& __m, last_spec) noexcept
1241 { return month_day_last{__m}; }
1243 friend constexpr month_day_last
1244 operator/(int __m, last_spec) noexcept
1245 { return chrono::month(unsigned(__m)) / last; }
1247 friend constexpr month_day_last
1248 operator/(last_spec, const chrono::month& __m) noexcept
1249 { return __m / last; }
1251 friend constexpr month_day_last
1252 operator/(last_spec, int __m) noexcept
1253 { return __m / last; }
1255 friend constexpr year_month_day_last
1256 operator/(int __y, const month_day_last& __mdl) noexcept;
1258 friend constexpr year_month_day_last
1259 operator/(const month_day_last& __mdl, int __y) noexcept;
1268 chrono::weekday_indexed _M_wdi;
1272 month_weekday(const chrono::month& __m,
1273 const chrono::weekday_indexed& __wdi) noexcept
1274 : _M_m{__m}, _M_wdi{__wdi}
1277 constexpr chrono::month
1278 month() const noexcept
1281 constexpr chrono::weekday_indexed
1282 weekday_indexed() const noexcept
1287 { return _M_m.ok() && _M_wdi.ok(); }
1289 friend constexpr bool
1290 operator==(const month_weekday& __x, const month_weekday& __y) noexcept
1292 return __x.month() == __y.month()
1293 && __x.weekday_indexed() == __y.weekday_indexed();
1296 friend constexpr month_weekday
1297 operator/(const chrono::month& __m,
1298 const chrono::weekday_indexed& __wdi) noexcept
1299 { return {__m, __wdi}; }
1301 friend constexpr month_weekday
1302 operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1303 { return chrono::month(unsigned(__m)) / __wdi; }
1305 friend constexpr month_weekday
1306 operator/(const chrono::weekday_indexed& __wdi,
1307 const chrono::month& __m) noexcept
1308 { return __m / __wdi; }
1310 friend constexpr month_weekday
1311 operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1312 { return __m / __wdi; }
1314 friend constexpr year_month_weekday
1315 operator/(int __y, const month_weekday& __mwd) noexcept;
1317 friend constexpr year_month_weekday
1318 operator/(const month_weekday& __mwd, int __y) noexcept;
1321 // MONTH_WEEKDAY_LAST
1323 class month_weekday_last
1327 chrono::weekday_last _M_wdl;
1331 month_weekday_last(const chrono::month& __m,
1332 const chrono::weekday_last& __wdl) noexcept
1333 :_M_m{__m}, _M_wdl{__wdl}
1336 constexpr chrono::month
1337 month() const noexcept
1340 constexpr chrono::weekday_last
1341 weekday_last() const noexcept
1346 { return _M_m.ok() && _M_wdl.ok(); }
1348 friend constexpr bool
1349 operator==(const month_weekday_last& __x,
1350 const month_weekday_last& __y) noexcept
1352 return __x.month() == __y.month()
1353 && __x.weekday_last() == __y.weekday_last();
1356 friend constexpr month_weekday_last
1357 operator/(const chrono::month& __m,
1358 const chrono::weekday_last& __wdl) noexcept
1359 { return {__m, __wdl}; }
1361 friend constexpr month_weekday_last
1362 operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1363 { return chrono::month(unsigned(__m)) / __wdl; }
1365 friend constexpr month_weekday_last
1366 operator/(const chrono::weekday_last& __wdl,
1367 const chrono::month& __m) noexcept
1368 { return __m / __wdl; }
1370 friend constexpr month_weekday_last
1371 operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1372 { return chrono::month(unsigned(__m)) / __wdl; }
1374 friend constexpr year_month_weekday_last
1375 operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1377 friend constexpr year_month_weekday_last
1378 operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1385 // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1386 // addition/subtraction operator overloads like so:
1388 // Constraints: if the argument supplied by the caller for the months
1389 // parameter is convertible to years, its implicit conversion sequence
1390 // to years is worse than its implicit conversion sequence to months.
1392 // We realize this constraint by templatizing the 'months'-based
1393 // overloads (using a dummy defaulted template parameter), so that
1394 // overload resolution doesn't select the 'months'-based overload unless
1395 // the implicit conversion sequence to 'months' is better than that to
1397 using __months_years_conversion_disambiguator = void;
1407 year_month() = default;
1410 year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1411 : _M_y{__y}, _M_m{__m}
1414 constexpr chrono::year
1415 year() const noexcept
1418 constexpr chrono::month
1419 month() const noexcept
1422 template<typename = __detail::__months_years_conversion_disambiguator>
1423 constexpr year_month&
1424 operator+=(const months& __dm) noexcept
1426 *this = *this + __dm;
1430 template<typename = __detail::__months_years_conversion_disambiguator>
1431 constexpr year_month&
1432 operator-=(const months& __dm) noexcept
1434 *this = *this - __dm;
1438 constexpr year_month&
1439 operator+=(const years& __dy) noexcept
1441 *this = *this + __dy;
1445 constexpr year_month&
1446 operator-=(const years& __dy) noexcept
1448 *this = *this - __dy;
1454 { return _M_y.ok() && _M_m.ok(); }
1456 friend constexpr bool
1457 operator==(const year_month& __x, const year_month& __y) noexcept
1458 { return __x.year() == __y.year() && __x.month() == __y.month(); }
1460 friend constexpr strong_ordering
1461 operator<=>(const year_month& __x, const year_month& __y) noexcept
1464 template<typename = __detail::__months_years_conversion_disambiguator>
1465 friend constexpr year_month
1466 operator+(const year_month& __ym, const months& __dm) noexcept
1469 auto __m = __ym.month() + __dm;
1470 auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1472 ? __ym.year() + years{(__i - 11) / 12}
1473 : __ym.year() + years{__i / 12});
1477 template<typename = __detail::__months_years_conversion_disambiguator>
1478 friend constexpr year_month
1479 operator+(const months& __dm, const year_month& __ym) noexcept
1480 { return __ym + __dm; }
1482 template<typename = __detail::__months_years_conversion_disambiguator>
1483 friend constexpr year_month
1484 operator-(const year_month& __ym, const months& __dm) noexcept
1485 { return __ym + -__dm; }
1487 friend constexpr months
1488 operator-(const year_month& __x, const year_month& __y) noexcept
1490 return (__x.year() - __y.year()
1491 + months{static_cast<int>(unsigned{__x.month()})
1492 - static_cast<int>(unsigned{__y.month()})});
1495 friend constexpr year_month
1496 operator+(const year_month& __ym, const years& __dy) noexcept
1497 { return (__ym.year() + __dy) / __ym.month(); }
1499 friend constexpr year_month
1500 operator+(const years& __dy, const year_month& __ym) noexcept
1501 { return __ym + __dy; }
1503 friend constexpr year_month
1504 operator-(const year_month& __ym, const years& __dy) noexcept
1505 { return __ym + -__dy; }
1507 friend constexpr year_month
1508 operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1509 { return {__y, __m}; }
1511 friend constexpr year_month
1512 operator/(const chrono::year& __y, int __m) noexcept
1513 { return {__y, chrono::month(unsigned(__m))}; }
1515 friend constexpr year_month_day
1516 operator/(const year_month& __ym, int __d) noexcept;
1518 friend constexpr year_month_day_last
1519 operator/(const year_month& __ym, last_spec) noexcept;
1524 class year_month_day
1531 static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1533 constexpr days _M_days_since_epoch() const noexcept;
1536 year_month_day() = default;
1539 year_month_day(const chrono::year& __y, const chrono::month& __m,
1540 const chrono::day& __d) noexcept
1541 : _M_y{__y}, _M_m{__m}, _M_d{__d}
1545 year_month_day(const year_month_day_last& __ymdl) noexcept;
1548 year_month_day(const sys_days& __dp) noexcept
1549 : year_month_day(_S_from_days(__dp.time_since_epoch()))
1553 year_month_day(const local_days& __dp) noexcept
1554 : year_month_day(sys_days{__dp.time_since_epoch()})
1557 template<typename = __detail::__months_years_conversion_disambiguator>
1558 constexpr year_month_day&
1559 operator+=(const months& __m) noexcept
1561 *this = *this + __m;
1565 template<typename = __detail::__months_years_conversion_disambiguator>
1566 constexpr year_month_day&
1567 operator-=(const months& __m) noexcept
1569 *this = *this - __m;
1573 constexpr year_month_day&
1574 operator+=(const years& __y) noexcept
1576 *this = *this + __y;
1580 constexpr year_month_day&
1581 operator-=(const years& __y) noexcept
1583 *this = *this - __y;
1587 constexpr chrono::year
1588 year() const noexcept
1591 constexpr chrono::month
1592 month() const noexcept
1595 constexpr chrono::day
1596 day() const noexcept
1600 operator sys_days() const noexcept
1601 { return sys_days{_M_days_since_epoch()}; }
1604 operator local_days() const noexcept
1605 { return local_days{sys_days{*this}.time_since_epoch()}; }
1607 constexpr bool ok() const noexcept;
1609 friend constexpr bool
1610 operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1612 return __x.year() == __y.year()
1613 && __x.month() == __y.month()
1614 && __x.day() == __y.day();
1617 friend constexpr strong_ordering
1618 operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1621 template<typename = __detail::__months_years_conversion_disambiguator>
1622 friend constexpr year_month_day
1623 operator+(const year_month_day& __ymd, const months& __dm) noexcept
1624 { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1626 template<typename = __detail::__months_years_conversion_disambiguator>
1627 friend constexpr year_month_day
1628 operator+(const months& __dm, const year_month_day& __ymd) noexcept
1629 { return __ymd + __dm; }
1631 friend constexpr year_month_day
1632 operator+(const year_month_day& __ymd, const years& __dy) noexcept
1633 { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1635 friend constexpr year_month_day
1636 operator+(const years& __dy, const year_month_day& __ymd) noexcept
1637 { return __ymd + __dy; }
1639 template<typename = __detail::__months_years_conversion_disambiguator>
1640 friend constexpr year_month_day
1641 operator-(const year_month_day& __ymd, const months& __dm) noexcept
1642 { return __ymd + -__dm; }
1644 friend constexpr year_month_day
1645 operator-(const year_month_day& __ymd, const years& __dy) noexcept
1646 { return __ymd + -__dy; }
1648 friend constexpr year_month_day
1649 operator/(const year_month& __ym, const chrono::day& __d) noexcept
1650 { return {__ym.year(), __ym.month(), __d}; }
1652 friend constexpr year_month_day
1653 operator/(const year_month& __ym, int __d) noexcept
1654 { return __ym / chrono::day{unsigned(__d)}; }
1656 friend constexpr year_month_day
1657 operator/(const chrono::year& __y, const month_day& __md) noexcept
1658 { return __y / __md.month() / __md.day(); }
1660 friend constexpr year_month_day
1661 operator/(int __y, const month_day& __md) noexcept
1662 { return chrono::year{__y} / __md; }
1664 friend constexpr year_month_day
1665 operator/(const month_day& __md, const chrono::year& __y) noexcept
1666 { return __y / __md; }
1668 friend constexpr year_month_day
1669 operator/(const month_day& __md, int __y) noexcept
1670 { return chrono::year(__y) / __md; }
1673 // Construct from days since 1970/01/01.
1674 // Proposition 6.3 of Neri and Schneider,
1675 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1676 // https://arxiv.org/abs/2102.06959
1677 constexpr year_month_day
1678 year_month_day::_S_from_days(const days& __dp) noexcept
1680 constexpr auto __z2 = static_cast<uint32_t>(-1468000);
1681 constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1683 const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1685 const auto __n1 = 4 * __r0 + 3;
1686 const auto __q1 = __n1 / 146097;
1687 const auto __r1 = __n1 % 146097 / 4;
1689 constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1690 const auto __n2 = 4 * __r1 + 3;
1691 const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1692 const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1693 const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1695 constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1696 const auto __n3 = 2141 * __r2 + 197913;
1697 const auto __q3 = __n3 / __p16;
1698 const auto __r3 = __n3 % __p16 / 2141;
1700 const auto __y0 = 100 * __q1 + __q2;
1701 const auto __m0 = __q3;
1702 const auto __d0 = __r3;
1704 const auto __j = __r2 >= 306;
1705 const auto __y1 = __y0 + __j;
1706 const auto __m1 = __j ? __m0 - 12 : __m0;
1707 const auto __d1 = __d0 + 1;
1709 return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1710 chrono::month{__m1}, chrono::day{__d1}};
1713 // Days since 1970/01/01.
1714 // Proposition 6.2 of Neri and Schneider,
1715 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1716 // https://arxiv.org/abs/2102.06959
1718 year_month_day::_M_days_since_epoch() const noexcept
1720 auto constexpr __z2 = static_cast<uint32_t>(-1468000);
1721 auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1723 const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1724 const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1725 const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1727 const auto __j = static_cast<uint32_t>(__m1 < 3);
1728 const auto __y0 = __y1 - __j;
1729 const auto __m0 = __j ? __m1 + 12 : __m1;
1730 const auto __d0 = __d1 - 1;
1732 const auto __q1 = __y0 / 100;
1733 const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1734 const auto __mc = (979 *__m0 - 2919) / 32;
1735 const auto __dc = __d0;
1737 return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1740 // YEAR_MONTH_DAY_LAST
1742 class year_month_day_last
1746 chrono::month_day_last _M_mdl;
1750 year_month_day_last(const chrono::year& __y,
1751 const chrono::month_day_last& __mdl) noexcept
1752 : _M_y{__y}, _M_mdl{__mdl}
1755 template<typename = __detail::__months_years_conversion_disambiguator>
1756 constexpr year_month_day_last&
1757 operator+=(const months& __m) noexcept
1759 *this = *this + __m;
1763 template<typename = __detail::__months_years_conversion_disambiguator>
1764 constexpr year_month_day_last&
1765 operator-=(const months& __m) noexcept
1767 *this = *this - __m;
1771 constexpr year_month_day_last&
1772 operator+=(const years& __y) noexcept
1774 *this = *this + __y;
1778 constexpr year_month_day_last&
1779 operator-=(const years& __y) noexcept
1781 *this = *this - __y;
1785 constexpr chrono::year
1786 year() const noexcept
1789 constexpr chrono::month
1790 month() const noexcept
1791 { return _M_mdl.month(); }
1793 constexpr chrono::month_day_last
1794 month_day_last() const noexcept
1797 // Return A day representing the last day of this year, month pair.
1798 constexpr chrono::day
1799 day() const noexcept
1801 const auto __m = static_cast<unsigned>(month());
1803 // The result is unspecified if __m < 1 or __m > 12. Hence, assume
1804 // 1 <= __m <= 12. For __m != 2, day() == 30 or day() == 31 or, in
1805 // other words, day () == 30 | b, where b is in {0, 1}.
1807 // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
1808 // odd. Hence, b = __m & 1 = (__m ^ 0) & 1.
1810 // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
1811 // even. Hence, b = (__m ^ 1) & 1.
1813 // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1814 // __m >= 8, that is, c = __m >> 3.
1816 // Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1817 // calculation is unnecessary.
1819 // The performance of this implementation does not depend on look-up
1820 // tables being on the L1 cache.
1821 return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
1822 : _M_y.is_leap() ? 29 : 28};
1826 operator sys_days() const noexcept
1827 { return sys_days{year() / month() / day()}; }
1830 operator local_days() const noexcept
1831 { return local_days{sys_days{*this}.time_since_epoch()}; }
1835 { return _M_y.ok() && _M_mdl.ok(); }
1837 friend constexpr bool
1838 operator==(const year_month_day_last& __x,
1839 const year_month_day_last& __y) noexcept
1841 return __x.year() == __y.year()
1842 && __x.month_day_last() == __y.month_day_last();
1845 friend constexpr strong_ordering
1846 operator<=>(const year_month_day_last& __x,
1847 const year_month_day_last& __y) noexcept
1850 template<typename = __detail::__months_years_conversion_disambiguator>
1851 friend constexpr year_month_day_last
1852 operator+(const year_month_day_last& __ymdl,
1853 const months& __dm) noexcept
1854 { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1856 template<typename = __detail::__months_years_conversion_disambiguator>
1857 friend constexpr year_month_day_last
1858 operator+(const months& __dm,
1859 const year_month_day_last& __ymdl) noexcept
1860 { return __ymdl + __dm; }
1862 template<typename = __detail::__months_years_conversion_disambiguator>
1863 friend constexpr year_month_day_last
1864 operator-(const year_month_day_last& __ymdl,
1865 const months& __dm) noexcept
1866 { return __ymdl + -__dm; }
1868 friend constexpr year_month_day_last
1869 operator+(const year_month_day_last& __ymdl,
1870 const years& __dy) noexcept
1871 { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1873 friend constexpr year_month_day_last
1874 operator+(const years& __dy,
1875 const year_month_day_last& __ymdl) noexcept
1876 { return __ymdl + __dy; }
1878 friend constexpr year_month_day_last
1879 operator-(const year_month_day_last& __ymdl,
1880 const years& __dy) noexcept
1881 { return __ymdl + -__dy; }
1883 friend constexpr year_month_day_last
1884 operator/(const year_month& __ym, last_spec) noexcept
1885 { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1887 friend constexpr year_month_day_last
1888 operator/(const chrono::year& __y,
1889 const chrono::month_day_last& __mdl) noexcept
1890 { return {__y, __mdl}; }
1892 friend constexpr year_month_day_last
1893 operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1894 { return chrono::year(__y) / __mdl; }
1896 friend constexpr year_month_day_last
1897 operator/(const chrono::month_day_last& __mdl,
1898 const chrono::year& __y) noexcept
1899 { return __y / __mdl; }
1901 friend constexpr year_month_day_last
1902 operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1903 { return chrono::year(__y) / __mdl; }
1906 // year_month_day ctor from year_month_day_last
1908 year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1909 : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1913 year_month_day::ok() const noexcept
1915 if (!_M_y.ok() || !_M_m.ok())
1917 return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1920 // YEAR_MONTH_WEEKDAY
1922 class year_month_weekday
1927 chrono::weekday_indexed _M_wdi;
1929 static constexpr year_month_weekday
1930 _S_from_sys_days(const sys_days& __dp)
1932 year_month_day __ymd{__dp};
1933 chrono::weekday __wd{__dp};
1934 auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1935 return {__ymd.year(), __ymd.month(), __index};
1939 year_month_weekday() = default;
1942 year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1943 const chrono::weekday_indexed& __wdi) noexcept
1944 : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1948 year_month_weekday(const sys_days& __dp) noexcept
1949 : year_month_weekday{_S_from_sys_days(__dp)}
1953 year_month_weekday(const local_days& __dp) noexcept
1954 : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1957 template<typename = __detail::__months_years_conversion_disambiguator>
1958 constexpr year_month_weekday&
1959 operator+=(const months& __m) noexcept
1961 *this = *this + __m;
1965 template<typename = __detail::__months_years_conversion_disambiguator>
1966 constexpr year_month_weekday&
1967 operator-=(const months& __m) noexcept
1969 *this = *this - __m;
1973 constexpr year_month_weekday&
1974 operator+=(const years& __y) noexcept
1976 *this = *this + __y;
1980 constexpr year_month_weekday&
1981 operator-=(const years& __y) noexcept
1983 *this = *this - __y;
1987 constexpr chrono::year
1988 year() const noexcept
1991 constexpr chrono::month
1992 month() const noexcept
1995 constexpr chrono::weekday
1996 weekday() const noexcept
1997 { return _M_wdi.weekday(); }
2000 index() const noexcept
2001 { return _M_wdi.index(); }
2003 constexpr chrono::weekday_indexed
2004 weekday_indexed() const noexcept
2008 operator sys_days() const noexcept
2010 auto __d = sys_days{year() / month() / 1};
2011 return __d + (weekday() - chrono::weekday(__d)
2012 + days{(static_cast<int>(index())-1)*7});
2016 operator local_days() const noexcept
2017 { return local_days{sys_days{*this}.time_since_epoch()}; }
2022 if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
2024 if (_M_wdi.index() <= 4)
2026 days __d = (_M_wdi.weekday()
2027 - chrono::weekday{sys_days{_M_y / _M_m / 1}}
2028 + days((_M_wdi.index()-1)*7 + 1));
2029 __glibcxx_assert(__d.count() >= 1);
2030 return (unsigned)__d.count() <= (unsigned)(_M_y / _M_m / last).day();
2033 friend constexpr bool
2034 operator==(const year_month_weekday& __x,
2035 const year_month_weekday& __y) noexcept
2037 return __x.year() == __y.year()
2038 && __x.month() == __y.month()
2039 && __x.weekday_indexed() == __y.weekday_indexed();
2042 template<typename = __detail::__months_years_conversion_disambiguator>
2043 friend constexpr year_month_weekday
2044 operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
2046 return ((__ymwd.year() / __ymwd.month() + __dm)
2047 / __ymwd.weekday_indexed());
2050 template<typename = __detail::__months_years_conversion_disambiguator>
2051 friend constexpr year_month_weekday
2052 operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
2053 { return __ymwd + __dm; }
2055 friend constexpr year_month_weekday
2056 operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
2057 { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
2059 friend constexpr year_month_weekday
2060 operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2061 { return __ymwd + __dy; }
2063 template<typename = __detail::__months_years_conversion_disambiguator>
2064 friend constexpr year_month_weekday
2065 operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
2066 { return __ymwd + -__dm; }
2068 friend constexpr year_month_weekday
2069 operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2070 { return __ymwd + -__dy; }
2072 friend constexpr year_month_weekday
2073 operator/(const year_month& __ym,
2074 const chrono::weekday_indexed& __wdi) noexcept
2075 { return {__ym.year(), __ym.month(), __wdi}; }
2077 friend constexpr year_month_weekday
2078 operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
2079 { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
2081 friend constexpr year_month_weekday
2082 operator/(int __y, const month_weekday& __mwd) noexcept
2083 { return chrono::year(__y) / __mwd; }
2085 friend constexpr year_month_weekday
2086 operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2087 { return __y / __mwd; }
2089 friend constexpr year_month_weekday
2090 operator/(const month_weekday& __mwd, int __y) noexcept
2091 { return chrono::year(__y) / __mwd; }
2094 // YEAR_MONTH_WEEKDAY_LAST
2096 class year_month_weekday_last
2101 chrono::weekday_last _M_wdl;
2105 year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
2106 const chrono::weekday_last& __wdl) noexcept
2107 : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
2110 template<typename = __detail::__months_years_conversion_disambiguator>
2111 constexpr year_month_weekday_last&
2112 operator+=(const months& __m) noexcept
2114 *this = *this + __m;
2118 template<typename = __detail::__months_years_conversion_disambiguator>
2119 constexpr year_month_weekday_last&
2120 operator-=(const months& __m) noexcept
2122 *this = *this - __m;
2126 constexpr year_month_weekday_last&
2127 operator+=(const years& __y) noexcept
2129 *this = *this + __y;
2133 constexpr year_month_weekday_last&
2134 operator-=(const years& __y) noexcept
2136 *this = *this - __y;
2140 constexpr chrono::year
2141 year() const noexcept
2144 constexpr chrono::month
2145 month() const noexcept
2148 constexpr chrono::weekday
2149 weekday() const noexcept
2150 { return _M_wdl.weekday(); }
2152 constexpr chrono::weekday_last
2153 weekday_last() const noexcept
2157 operator sys_days() const noexcept
2159 const auto __d = sys_days{_M_y / _M_m / last};
2160 return sys_days{(__d - (chrono::weekday{__d}
2161 - _M_wdl.weekday())).time_since_epoch()};
2165 operator local_days() const noexcept
2166 { return local_days{sys_days{*this}.time_since_epoch()}; }
2170 { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2172 friend constexpr bool
2173 operator==(const year_month_weekday_last& __x,
2174 const year_month_weekday_last& __y) noexcept
2176 return __x.year() == __y.year()
2177 && __x.month() == __y.month()
2178 && __x.weekday_last() == __y.weekday_last();
2181 template<typename = __detail::__months_years_conversion_disambiguator>
2182 friend constexpr year_month_weekday_last
2183 operator+(const year_month_weekday_last& __ymwdl,
2184 const months& __dm) noexcept
2186 return ((__ymwdl.year() / __ymwdl.month() + __dm)
2187 / __ymwdl.weekday_last());
2190 template<typename = __detail::__months_years_conversion_disambiguator>
2191 friend constexpr year_month_weekday_last
2192 operator+(const months& __dm,
2193 const year_month_weekday_last& __ymwdl) noexcept
2194 { return __ymwdl + __dm; }
2196 friend constexpr year_month_weekday_last
2197 operator+(const year_month_weekday_last& __ymwdl,
2198 const years& __dy) noexcept
2199 { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
2201 friend constexpr year_month_weekday_last
2202 operator+(const years& __dy,
2203 const year_month_weekday_last& __ymwdl) noexcept
2204 { return __ymwdl + __dy; }
2206 template<typename = __detail::__months_years_conversion_disambiguator>
2207 friend constexpr year_month_weekday_last
2208 operator-(const year_month_weekday_last& __ymwdl,
2209 const months& __dm) noexcept
2210 { return __ymwdl + -__dm; }
2212 friend constexpr year_month_weekday_last
2213 operator-(const year_month_weekday_last& __ymwdl,
2214 const years& __dy) noexcept
2215 { return __ymwdl + -__dy; }
2217 friend constexpr year_month_weekday_last
2218 operator/(const year_month& __ym,
2219 const chrono::weekday_last& __wdl) noexcept
2220 { return {__ym.year(), __ym.month(), __wdl}; }
2222 friend constexpr year_month_weekday_last
2223 operator/(const chrono::year& __y,
2224 const chrono::month_weekday_last& __mwdl) noexcept
2225 { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
2227 friend constexpr year_month_weekday_last
2228 operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2229 { return chrono::year(__y) / __mwdl; }
2231 friend constexpr year_month_weekday_last
2232 operator/(const chrono::month_weekday_last& __mwdl,
2233 const chrono::year& __y) noexcept
2234 { return __y / __mwdl; }
2236 friend constexpr year_month_weekday_last
2237 operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
2238 { return chrono::year(__y) / __mwdl; }
2243 /// @cond undocumented
2247 __pow10(unsigned __n)
2255 template<typename _Duration> struct __utc_leap_second;
2259 /** Utility for splitting a duration into hours, minutes, and seconds
2261 * This is a convenience type that provides accessors for the constituent
2262 * parts (hours, minutes, seconds and subseconds) of a duration.
2266 template<typename _Duration>
2269 static_assert( __is_duration<_Duration>::value );
2272 static consteval int
2273 _S_fractional_width()
2275 auto __den = _Duration::period::den;
2276 const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
2277 __den >>= __multiplicity_2;
2278 int __multiplicity_5 = 0;
2279 while ((__den % 5) == 0)
2287 int __width = (__multiplicity_2 > __multiplicity_5
2288 ? __multiplicity_2 : __multiplicity_5);
2295 hh_mm_ss(_Duration __d, bool __is_neg)
2296 : _M_h (duration_cast<chrono::hours>(__d)),
2297 _M_m (duration_cast<chrono::minutes>(__d - hours())),
2298 _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
2301 auto __ss = __d - hours() - minutes() - seconds();
2302 if constexpr (treat_as_floating_point_v<typename precision::rep>)
2303 _M_ss._M_r = __ss.count();
2304 else if constexpr (precision::period::den != 1)
2305 _M_ss._M_r = duration_cast<precision>(__ss).count();
2308 static constexpr _Duration
2309 _S_abs(_Duration __d)
2311 if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
2312 return chrono::abs(__d);
2318 static constexpr unsigned fractional_width = {_S_fractional_width()};
2321 = duration<common_type_t<typename _Duration::rep,
2322 chrono::seconds::rep>,
2323 ratio<1, __detail::__pow10(fractional_width)>>;
2325 constexpr hh_mm_ss() noexcept = default;
2328 hh_mm_ss(_Duration __d)
2329 : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2333 is_negative() const noexcept
2335 if constexpr (!_S_is_unsigned)
2341 constexpr chrono::hours
2342 hours() const noexcept
2345 constexpr chrono::minutes
2346 minutes() const noexcept
2349 constexpr chrono::seconds
2350 seconds() const noexcept
2354 subseconds() const noexcept
2355 { return static_cast<precision>(_M_ss); }
2358 operator precision() const noexcept
2359 { return to_duration(); }
2362 to_duration() const noexcept
2364 if constexpr (!_S_is_unsigned)
2366 return -(_M_h + _M_m + _M_s + subseconds());
2367 return _M_h + _M_m + _M_s + subseconds();
2371 static constexpr bool _S_is_unsigned
2372 = __and_v<is_integral<typename _Duration::rep>,
2373 is_unsigned<typename _Duration::rep>>;
2375 template<typename _Ratio>
2376 using __byte_duration = duration<unsigned char, _Ratio>;
2378 // The type of the _M_ss member that holds the subsecond precision.
2379 template<typename _Dur>
2382 typename _Dur::rep _M_r{};
2385 operator _Dur() const noexcept
2386 { return _Dur(_M_r); }
2389 // An empty class if this precision doesn't need subseconds.
2390 template<typename _Rep>
2391 requires (!treat_as_floating_point_v<_Rep>)
2392 struct __subseconds<duration<_Rep, ratio<1>>>
2395 operator duration<_Rep, ratio<1>>() const noexcept
2399 template<typename _Rep, typename _Period>
2400 requires (!treat_as_floating_point_v<_Rep>)
2401 && ratio_less_v<_Period, ratio<1, 1>>
2402 && ratio_greater_equal_v<_Period, ratio<1, 250>>
2403 struct __subseconds<duration<_Rep, _Period>>
2405 unsigned char _M_r{};
2408 operator duration<_Rep, _Period>() const noexcept
2409 { return duration<_Rep, _Period>(_M_r); }
2412 template<typename _Rep, typename _Period>
2413 requires (!treat_as_floating_point_v<_Rep>)
2414 && ratio_less_v<_Period, ratio<1, 250>>
2415 && ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
2416 struct __subseconds<duration<_Rep, _Period>>
2418 uint_least32_t _M_r{};
2421 operator duration<_Rep, _Period>() const noexcept
2422 { return duration<_Rep, _Period>(_M_r); }
2425 chrono::hours _M_h{};
2426 __byte_duration<ratio<60>> _M_m{};
2427 __byte_duration<ratio<1>> _M_s{};
2429 __subseconds<precision> _M_ss{};
2431 template<typename> friend struct __detail::__utc_leap_second;
2434 /// @cond undocumented
2437 // Represents a time that is within a leap second insertion.
2438 template<typename _Duration>
2439 struct __utc_leap_second
2442 __utc_leap_second(const sys_time<_Duration>& __s)
2443 : _M_date(chrono::floor<days>(__s)), _M_time(__s - _M_date)
2449 hh_mm_ss<common_type_t<_Duration, days>> _M_time;
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 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2494 // C++20 [time.zones] Time zones
2509 static constexpr int unique = 0;
2510 static constexpr int nonexistent = 1;
2511 static constexpr int ambiguous = 2;
2518 class nonexistent_local_time : public runtime_error
2521 template<typename _Duration>
2522 nonexistent_local_time(const local_time<_Duration>& __tp,
2523 const local_info& __i)
2524 : runtime_error(_S_make_what_str(__tp, __i))
2525 { __glibcxx_assert(__i.result == local_info::nonexistent); }
2528 template<typename _Duration>
2530 _S_make_what_str(const local_time<_Duration>& __tp,
2531 const local_info& __i)
2533 std::ostringstream __os;
2534 __os << __tp << " is in a gap between\n"
2535 << local_seconds(__i.first.end.time_since_epoch())
2536 + __i.first.offset << ' ' << __i.first.abbrev << " and\n"
2537 << local_seconds(__i.second.begin.time_since_epoch())
2538 + __i.second.offset << ' ' << __i.second.abbrev
2539 << " which are both equivalent to\n"
2540 << __i.first.end << " UTC";
2541 return std::move(__os).str();
2545 class ambiguous_local_time : public runtime_error
2548 template<typename _Duration>
2549 ambiguous_local_time(const local_time<_Duration>& __tp,
2550 const local_info& __i)
2551 : runtime_error(_S_make_what_str(__tp, __i))
2552 { __glibcxx_assert(__i.result == local_info::ambiguous); }
2555 template<typename _Duration>
2557 _S_make_what_str(const local_time<_Duration>& __tp,
2558 const local_info& __i)
2560 std::ostringstream __os;
2561 __os << __tp << " is ambiguous. It could be\n"
2562 << __tp << ' ' << __i.first.abbrev << " == "
2563 << __tp - __i.first.offset << " UTC or\n"
2564 << __tp << ' ' << __i.second.abbrev << " == "
2565 << __tp - __i.second.offset << " UTC";
2566 return std::move(__os).str();
2570 template<typename _Duration>
2572 __throw_bad_local_time(const local_time<_Duration>& __tp,
2573 const local_info& __i)
2575 #if __cpp_exceptions
2576 if (__i.result == local_info::nonexistent)
2577 throw nonexistent_local_time(__tp, __i);
2578 throw ambiguous_local_time(__tp, __i);
2584 enum class choose { earliest, latest };
2589 time_zone(time_zone&&) = default;
2590 time_zone& operator=(time_zone&&) = default;
2595 string_view name() const noexcept { return _M_name; }
2597 template<typename _Duration>
2599 get_info(const sys_time<_Duration>& __st) const
2600 { return _M_get_sys_info(chrono::floor<seconds>(__st)); }
2602 template<typename _Duration>
2604 get_info(const local_time<_Duration>& __tp) const
2605 { return _M_get_local_info(chrono::floor<seconds>(__tp)); }
2607 template<typename _Duration>
2608 sys_time<common_type_t<_Duration, seconds>>
2609 to_sys(const local_time<_Duration>& __tp) const
2611 local_info __info = get_info(__tp);
2613 if (__info.result != local_info::unique)
2614 __throw_bad_local_time(__tp, __info);
2616 return sys_time<_Duration>(__tp.time_since_epoch())
2617 - __info.first.offset;
2620 template<typename _Duration>
2621 sys_time<common_type_t<_Duration, seconds>>
2622 to_sys(const local_time<_Duration>& __tp, choose __z) const
2624 local_info __info = get_info(__tp);
2626 if (__info.result == local_info::nonexistent)
2627 return __info.first.end; // Last second of the previous sys_info.
2629 sys_time<_Duration> __st(__tp.time_since_epoch());
2631 if (__info.result == local_info::ambiguous && __z == choose::latest)
2632 return __st - __info.second.offset; // Time in the later sys_info.
2633 // else if __z == earliest, use __info.first.offset as below:
2635 return __st - __info.first.offset;
2638 template<typename _Duration>
2639 local_time<common_type_t<_Duration, seconds>>
2640 to_local(const sys_time<_Duration>& __tp) const
2642 auto __d = (__tp + get_info(__tp).offset).time_since_epoch();
2643 return local_time<common_type_t<_Duration, seconds>>(__d);
2646 [[nodiscard]] friend bool
2647 operator==(const time_zone& __x, const time_zone& __y) noexcept
2648 { return __x._M_name == __y._M_name; }
2650 [[nodiscard]] friend strong_ordering
2651 operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2652 { return __x._M_name <=> __y._M_name; }
2655 sys_info _M_get_sys_info(sys_seconds) const;
2656 local_info _M_get_local_info(local_seconds) const;
2658 friend const tzdb& reload_tzdb();
2660 friend class tzdb_list;
2664 explicit time_zone(unique_ptr<_Impl> __p);
2666 unique_ptr<_Impl> _M_impl;
2669 const time_zone* locate_zone(string_view __tz_name);
2670 const time_zone* current_zone();
2672 /** The list of `chrono::tzdb` objects
2674 * A single object of this type is constructed by the C++ runtime,
2675 * and can be accessed by calling `chrono::get_tzdb_list()`.
2677 * The front of the list is the current `tzdb` object and can be accessed
2678 * via `chrono::get_tzdb_list().front()` or `chrono::get_tzdb()` or
2679 * `*chrono::get_tzdb_list().begin()`.
2681 * The `chrono::reload_tzdb()` function will check for a newer version
2682 * and if found, insert it at the front of the list.
2691 tzdb_list(const tzdb_list&) = delete;
2692 tzdb_list& operator=(const tzdb_list&) = delete;
2694 /** An iterator into the `tzdb_list`
2696 * As a extension, in libstdc++ each `tzdb` is reference-counted
2697 * and the `const_iterator` type shares ownership of the object it
2698 * refers to. This ensures that a `tzdb` erased from the list will
2699 * not be destroyed while there is an iterator that refers to it.
2701 class const_iterator
2704 using value_type = tzdb;
2705 using reference = const tzdb&;
2706 using pointer = const tzdb*;
2707 using difference_type = ptrdiff_t;
2708 using iterator_category = forward_iterator_tag;
2710 constexpr const_iterator() = default;
2711 const_iterator(const const_iterator&) = default;
2712 const_iterator(const_iterator&&) = default;
2713 const_iterator& operator=(const const_iterator&) = default;
2714 const_iterator& operator=(const_iterator&&) = default;
2716 reference operator*() const noexcept;
2717 pointer operator->() const noexcept { return &**this; }
2718 const_iterator& operator++();
2719 const_iterator operator++(int);
2721 bool operator==(const const_iterator&) const noexcept = default;
2724 explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2726 friend class tzdb_list;
2728 shared_ptr<_Node> _M_node;
2729 void* _M_reserved = nullptr;
2732 /** Access the current `tzdb` at the front of the list.
2734 * This returns a reference to the same object as `chrono::get_tzdb()`.
2736 * @returns A reference to the current tzdb object.
2739 const tzdb& front() const noexcept;
2741 /** Remove the tzdb object _after_ the one the iterator refers to.
2743 * Calling this function concurently with any of `front()`, `begin()`,
2744 * or `end()` does not cause a data race, but in general this function
2745 * is not thread-safe. The behaviour may be undefined if erasing an
2746 * element from the list while another thread is calling the same
2747 * function, or incrementing an iterator into the list, or accessing
2748 * the element being erased (unless it is accessed through an iterator).
2750 * @param __p A dereferenceable iterator.
2751 * @returns An iterator the element after the one that was erased
2752 * (or `end()` if there is no such element).
2755 const_iterator erase_after(const_iterator __p);
2757 const_iterator begin() const noexcept;
2758 const_iterator end() const noexcept { return {}; }
2759 const_iterator cbegin() const noexcept { return begin(); }
2760 const_iterator cend() const noexcept { return end(); }
2763 constexpr explicit tzdb_list(nullptr_t);
2765 friend tzdb_list& get_tzdb_list();
2766 friend const tzdb& get_tzdb();
2767 friend const tzdb& reload_tzdb();
2769 friend class leap_second;
2770 friend struct time_zone::_Impl;
2771 friend class time_zone_link;
2774 class time_zone_link
2777 time_zone_link(time_zone_link&&) = default;
2778 time_zone_link& operator=(time_zone_link&&) = default;
2780 string_view name() const noexcept { return _M_name; }
2781 string_view target() const noexcept { return _M_target; }
2784 operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2785 { return __x.name() == __y.name(); }
2787 friend strong_ordering
2788 operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2789 { return __x.name() <=> __y.name(); }
2792 friend const tzdb& reload_tzdb();
2793 friend struct tzdb_list::_Node;
2795 explicit time_zone_link(nullptr_t) { }
2804 leap_second(const leap_second&) = default;
2805 leap_second& operator=(const leap_second&) = default;
2808 constexpr sys_seconds
2809 date() const noexcept
2811 if (_M_s >= _M_s.zero()) [[likely]]
2812 return sys_seconds(_M_s);
2813 return sys_seconds(-_M_s);
2818 value() const noexcept
2820 if (_M_s >= _M_s.zero()) [[likely]]
2825 // This can be defaulted because the database will never contain two
2826 // leap_second objects with the same date but different signs.
2827 [[nodiscard]] friend constexpr bool
2828 operator==(const leap_second&, const leap_second&) noexcept = default;
2830 [[nodiscard]] friend constexpr strong_ordering
2831 operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2832 { return __x.date() <=> __y.date(); }
2834 template<typename _Duration>
2835 [[nodiscard]] friend constexpr bool
2836 operator==(const leap_second& __x,
2837 const sys_time<_Duration>& __y) noexcept
2838 { return __x.date() == __y; }
2840 template<typename _Duration>
2841 [[nodiscard]] friend constexpr bool
2842 operator<(const leap_second& __x,
2843 const sys_time<_Duration>& __y) noexcept
2844 { return __x.date() < __y; }
2846 template<typename _Duration>
2847 [[nodiscard]] friend constexpr bool
2848 operator<(const sys_time<_Duration>& __x,
2849 const leap_second& __y) noexcept
2850 { return __x < __y.date(); }
2852 template<typename _Duration>
2853 [[nodiscard]] friend constexpr bool
2854 operator>(const leap_second& __x,
2855 const sys_time<_Duration>& __y) noexcept
2856 { return __y < __x.date(); }
2858 template<typename _Duration>
2859 [[nodiscard]] friend constexpr bool
2860 operator>(const sys_time<_Duration>& __x,
2861 const leap_second& __y) noexcept
2862 { return __y.date() < __x; }
2864 template<typename _Duration>
2865 [[nodiscard]] friend constexpr bool
2866 operator<=(const leap_second& __x,
2867 const sys_time<_Duration>& __y) noexcept
2868 { return !(__y < __x.date()); }
2870 template<typename _Duration>
2871 [[nodiscard]] friend constexpr bool
2872 operator<=(const sys_time<_Duration>& __x,
2873 const leap_second& __y) noexcept
2874 { return !(__y.date() < __x); }
2876 template<typename _Duration>
2877 [[nodiscard]] friend constexpr bool
2878 operator>=(const leap_second& __x,
2879 const sys_time<_Duration>& __y) noexcept
2880 { return !(__x.date() < __y); }
2882 template<typename _Duration>
2883 [[nodiscard]] friend constexpr bool
2884 operator>=(const sys_time<_Duration>& __x,
2885 const leap_second& __y) noexcept
2886 { return !(__x < __y.date()); }
2888 template<three_way_comparable_with<seconds> _Duration>
2889 [[nodiscard]] friend constexpr auto
2890 operator<=>(const leap_second& __x,
2891 const sys_time<_Duration>& __y) noexcept
2892 { return __x.date() <=> __y; }
2895 explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2897 friend struct tzdb_list::_Node;
2899 friend const tzdb& reload_tzdb();
2901 template<typename _Duration>
2902 friend leap_second_info
2903 get_leap_second_info(const utc_time<_Duration>&);
2905 seconds _M_s; // == date().time_since_epoch() * value().count()
2908 template<class _Tp> struct zoned_traits { };
2911 struct zoned_traits<const time_zone*>
2913 static const time_zone*
2915 { return std::chrono::locate_zone("UTC"); }
2917 static const time_zone*
2918 locate_zone(string_view __name)
2919 { return std::chrono::locate_zone(__name); }
2925 _GLIBCXX_STD_C::vector<time_zone> zones;
2926 _GLIBCXX_STD_C::vector<time_zone_link> links;
2927 _GLIBCXX_STD_C::vector<leap_second> leap_seconds;
2930 locate_zone(string_view __tz_name) const;
2933 current_zone() const;
2936 friend const tzdb& reload_tzdb();
2937 friend class time_zone;
2938 friend struct tzdb_list::_Node;
2941 tzdb_list& get_tzdb_list();
2942 const tzdb& get_tzdb();
2944 const tzdb& reload_tzdb();
2945 string remote_version();
2947 template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2950 static_assert(__is_duration_v<_Duration>);
2952 using _Traits = zoned_traits<_TimeZonePtr>;
2954 // Every constructor that accepts a string_view as its first parameter
2955 // does not participate in class template argument deduction.
2956 using string_view = type_identity_t<std::string_view>;
2959 using duration = common_type_t<_Duration, seconds>;
2961 zoned_time() requires requires { _Traits::default_zone(); }
2964 zoned_time(const zoned_time&) = default;
2965 zoned_time& operator=(const zoned_time&) = default;
2967 zoned_time(const sys_time<_Duration>& __st)
2968 requires requires { _Traits::default_zone(); }
2973 zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
2976 zoned_time(string_view __name)
2978 _TimeZonePtr{_Traits::locate_zone(std::string_view{})};
2980 : _M_zone(_Traits::locate_zone(__name))
2983 template<typename _Duration2>
2984 zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)
2985 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
2986 : _M_zone(__zt._M_zone), _M_tp(__zt._M_tp)
2989 zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
2990 : _M_zone(std::move(__z)), _M_tp(__st)
2993 zoned_time(string_view __name, const sys_time<_Duration>& __st)
2994 : zoned_time(_Traits::locate_zone(__name), __st)
2997 zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp)
2999 { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3001 : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp))
3004 zoned_time(string_view __name, const local_time<_Duration>& __tp)
3005 requires requires (_TimeZonePtr __z) {
3006 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3007 { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3009 : zoned_time(_Traits::locate_zone(__name), __tp)
3012 zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp,
3015 { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3017 : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp, __c))
3020 zoned_time(string_view __name, const local_time<_Duration>& __tp,
3022 requires requires (_TimeZonePtr __z) {
3023 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3024 { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3026 : _M_zone(_Traits::locate_zone(__name)),
3027 _M_tp(_M_zone->to_sys(__tp, __c))
3030 template<typename _Duration2, typename _TimeZonePtr2>
3031 zoned_time(_TimeZonePtr __z,
3032 const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3033 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3034 : _M_zone(__z), _M_tp(__zt._M_tp)
3037 template<typename _Duration2, typename _TimeZonePtr2>
3038 zoned_time(_TimeZonePtr __z,
3039 const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3041 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3042 : _M_zone(__z), _M_tp(__zt._M_tp)
3045 template<typename _Duration2, typename _TimeZonePtr2>
3046 zoned_time(string_view __name,
3047 const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3048 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3050 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3052 : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3055 template<typename _Duration2, typename _TimeZonePtr2>
3056 zoned_time(string_view __name,
3057 const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3059 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3061 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3063 : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3067 operator=(const sys_time<_Duration>& __st)
3074 operator=(const local_time<_Duration>& __lt)
3076 _M_tp = _M_zone->to_sys(__lt);
3081 operator sys_time<duration>() const { return _M_tp; }
3084 explicit operator local_time<duration>() const
3085 { return get_local_time(); }
3089 get_time_zone() const
3093 local_time<duration>
3094 get_local_time() const
3095 { return _M_zone->to_local(_M_tp); }
3099 get_sys_time() const
3105 { return _M_zone->get_info(_M_tp); }
3107 [[nodiscard]] friend bool
3108 operator==(const zoned_time&, const zoned_time&) = default;
3111 _TimeZonePtr _M_zone{ _Traits::default_zone() };
3112 sys_time<duration> _M_tp{};
3114 template<typename _Duration2, typename _TimeZonePtr2>
3115 friend class zoned_time;
3118 zoned_time() -> zoned_time<seconds>;
3120 template<typename _Duration>
3121 zoned_time(sys_time<_Duration>)
3122 -> zoned_time<common_type_t<_Duration, seconds>>;
3124 /// @cond undocumented
3125 template<typename _TimeZonePtrOrName>
3126 using __time_zone_representation
3127 = __conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,
3129 remove_cvref_t<_TimeZonePtrOrName>>;
3132 template<typename _TimeZonePtrOrName>
3133 zoned_time(_TimeZonePtrOrName&&)
3134 -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
3136 template<typename _TimeZonePtrOrName, typename _Duration>
3137 zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)
3138 -> zoned_time<common_type_t<_Duration, seconds>,
3139 __time_zone_representation<_TimeZonePtrOrName>>;
3141 template<typename _TimeZonePtrOrName, typename _Duration>
3142 zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>,
3143 choose = choose::earliest)
3144 -> zoned_time<common_type_t<_Duration, seconds>,
3145 __time_zone_representation<_TimeZonePtrOrName>>;
3147 template<typename _Duration, typename _TimeZonePtrOrName,
3148 typename _TimeZonePtr2>
3149 zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>,
3150 choose = choose::earliest)
3151 -> zoned_time<common_type_t<_Duration, seconds>,
3152 __time_zone_representation<_TimeZonePtrOrName>>;
3154 template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
3157 operator==(const zoned_time<_Dur1, _TZPtr1>& __x,
3158 const zoned_time<_Dur2, _TZPtr2>& __y)
3160 return __x.get_time_zone() == __y.get_time_zone()
3161 && __x.get_sys_time() == __y.get_sys_time();
3164 using zoned_seconds = zoned_time<seconds>;
3165 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3169 inline leap_second_info
3170 __get_leap_second_info(sys_seconds __ss, bool __is_utc)
3172 if (__ss < sys_seconds{}) [[unlikely]]
3175 const seconds::rep __leaps[] {
3176 78796800, // 1 Jul 1972
3177 94694400, // 1 Jan 1973
3178 126230400, // 1 Jan 1974
3179 157766400, // 1 Jan 1975
3180 189302400, // 1 Jan 1976
3181 220924800, // 1 Jan 1977
3182 252460800, // 1 Jan 1978
3183 283996800, // 1 Jan 1979
3184 315532800, // 1 Jan 1980
3185 362793600, // 1 Jul 1981
3186 394329600, // 1 Jul 1982
3187 425865600, // 1 Jul 1983
3188 489024000, // 1 Jul 1985
3189 567993600, // 1 Jan 1988
3190 631152000, // 1 Jan 1990
3191 662688000, // 1 Jan 1991
3192 709948800, // 1 Jul 1992
3193 741484800, // 1 Jul 1993
3194 773020800, // 1 Jul 1994
3195 820454400, // 1 Jan 1996
3196 867715200, // 1 Jul 1997
3197 915148800, // 1 Jan 1999
3198 1136073600, // 1 Jan 2006
3199 1230768000, // 1 Jan 2009
3200 1341100800, // 1 Jul 2012
3201 1435708800, // 1 Jul 2015
3202 1483228800, // 1 Jan 2017
3204 // The list above is known to be valid until (at least) this date
3205 // and only contains positive leap seconds.
3206 const sys_seconds __expires(1703721600s); // 2023-12-28 00:00:00 UTC
3208 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3209 if (__ss > __expires)
3211 // Use updated leap_seconds from tzdb.
3212 size_t __n = std::size(__leaps);
3214 auto __db = get_tzdb_list().begin();
3215 auto __first = __db->leap_seconds.begin() + __n;
3216 auto __last = __db->leap_seconds.end();
3217 auto __pos = std::upper_bound(__first, __last, __ss);
3218 seconds __elapsed(__n);
3219 for (auto __i = __first; __i != __pos; ++__i)
3220 __elapsed += __i->value();
3224 // Convert utc_time to sys_time:
3226 // See if that sys_time is before (or during) previous leap sec:
3227 if (__pos != __first && __ss < __pos[-1])
3229 if ((__ss + 1s) >= __pos[-1])
3230 return {true, __elapsed};
3231 __elapsed -= __pos[-1].value();
3234 return {false, __elapsed};
3239 seconds::rep __s = __ss.time_since_epoch().count();
3240 const seconds::rep* __first = std::begin(__leaps);
3241 const seconds::rep* __last = std::end(__leaps);
3243 // Don't bother searching the list if we're after the last one.
3244 if (__s > (__last[-1] + (__last - __first) + 1))
3245 return { false, seconds(__last - __first) };
3247 auto __pos = std::upper_bound(__first, __last, __s);
3248 seconds __elapsed{__pos - __first};
3251 // Convert utc_time to sys_time:
3252 __s -= __elapsed.count();
3253 // See if that sys_time is before (or during) previous leap sec:
3254 if (__pos != __first && __s < __pos[-1])
3256 if ((__s + 1) >= __pos[-1])
3257 return {true, __elapsed};
3261 return {false, __elapsed};
3264 } // namespace __detail
3266 template<typename _Duration>
3268 inline leap_second_info
3269 get_leap_second_info(const utc_time<_Duration>& __ut)
3271 auto __s = chrono::duration_cast<seconds>(__ut.time_since_epoch());
3272 return __detail::__get_leap_second_info(sys_seconds(__s), true);
3275 template<typename _Duration>
3277 inline utc_time<common_type_t<_Duration, seconds>>
3278 utc_clock::from_sys(const sys_time<_Duration>& __t)
3280 using _CDur = common_type_t<_Duration, seconds>;
3281 auto __s = chrono::time_point_cast<seconds>(__t);
3282 const auto __li = __detail::__get_leap_second_info(__s, false);
3283 return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
3288 } // namespace chrono
3290 #if __cplusplus >= 202002L
3291 inline namespace literals
3293 inline namespace chrono_literals
3295 /// @addtogroup chrono
3297 #pragma GCC diagnostic push
3298 #pragma GCC diagnostic ignored "-Wliteral-suffix"
3299 /// Literal suffix for creating chrono::day objects.
3301 constexpr chrono::day
3302 operator""d(unsigned long long __d) noexcept
3303 { return chrono::day{static_cast<unsigned>(__d)}; }
3305 /// Literal suffix for creating chrono::year objects.
3307 constexpr chrono::year
3308 operator""y(unsigned long long __y) noexcept
3309 { return chrono::year{static_cast<int>(__y)}; }
3310 #pragma GCC diagnostic pop
3312 } // inline namespace chrono_literals
3313 } // inline namespace literals
3316 _GLIBCXX_END_NAMESPACE_VERSION
3319 #if __cplusplus >= 202002L
3320 # include <bits/chrono_io.h>
3325 #endif //_GLIBCXX_CHRONO