1 // <chrono> -*- C++ -*-
3 // Copyright (C) 2008-2024 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 #define __glibcxx_want_chrono
54 #define __glibcxx_want_chrono_udls
55 #include <bits/version.h>
57 namespace std _GLIBCXX_VISIBILITY(default)
59 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 * @defgroup chrono Time
65 * Classes and functions for time.
70 /** @namespace std::chrono
71 * @brief ISO C++ 2011 namespace for date and time utilities
76 #if __cplusplus >= 202002L
77 /// @addtogroup chrono
80 template<typename _Duration>
81 using local_time = time_point<local_t, _Duration>;
82 using local_seconds = local_time<seconds>;
83 using local_days = local_time<days>;
89 template<typename _Duration>
90 using utc_time = time_point<utc_clock, _Duration>;
91 using utc_seconds = utc_time<seconds>;
93 template<typename _Duration>
94 using tai_time = time_point<tai_clock, _Duration>;
95 using tai_seconds = tai_time<seconds>;
97 template<typename _Duration>
98 using gps_time = time_point<gps_clock, _Duration>;
99 using gps_seconds = gps_time<seconds>;
101 template<> struct is_clock<utc_clock> : true_type { };
102 template<> struct is_clock<tai_clock> : true_type { };
103 template<> struct is_clock<gps_clock> : true_type { };
105 template<> inline constexpr bool is_clock_v<utc_clock> = true;
106 template<> inline constexpr bool is_clock_v<tai_clock> = true;
107 template<> inline constexpr bool is_clock_v<gps_clock> = true;
109 struct leap_second_info
115 template<typename _Duration>
117 get_leap_second_info(const utc_time<_Duration>& __ut);
119 /** A clock that measures Universal Coordinated Time (UTC).
121 * The epoch is 1970-01-01 00:00:00.
128 using rep = system_clock::rep;
129 using period = system_clock::period;
130 using duration = chrono::duration<rep, period>;
131 using time_point = chrono::time_point<utc_clock>;
132 static constexpr bool is_steady = false;
137 { return from_sys(system_clock::now()); }
139 template<typename _Duration>
141 static sys_time<common_type_t<_Duration, seconds>>
142 to_sys(const utc_time<_Duration>& __t)
144 using _CDur = common_type_t<_Duration, seconds>;
145 const auto __li = chrono::get_leap_second_info(__t);
146 sys_time<_CDur> __s{__t.time_since_epoch() - __li.elapsed};
147 if (__li.is_leap_second)
148 __s = chrono::floor<seconds>(__s) + seconds{1} - _CDur{1};
152 template<typename _Duration>
154 static utc_time<common_type_t<_Duration, seconds>>
155 from_sys(const sys_time<_Duration>& __t);
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.
177 { return from_utc(utc_clock::now()); }
179 template<typename _Duration>
181 static utc_time<common_type_t<_Duration, seconds>>
182 to_utc(const tai_time<_Duration>& __t)
184 using _CDur = common_type_t<_Duration, seconds>;
185 return utc_time<_CDur>{__t.time_since_epoch()} - 378691210s;
188 template<typename _Duration>
190 static tai_time<common_type_t<_Duration, seconds>>
191 from_utc(const utc_time<_Duration>& __t)
193 using _CDur = common_type_t<_Duration, seconds>;
194 return tai_time<_CDur>{__t.time_since_epoch()} + 378691210s;
198 /** A clock that measures GPS time.
200 * The epoch is 1980-01-06 00:00:00.
207 using rep = system_clock::rep;
208 using period = system_clock::period;
209 using duration = chrono::duration<rep, period>;
210 using time_point = chrono::time_point<gps_clock>;
211 static constexpr bool is_steady = false; // XXX
213 // TODO move into lib, add extension point.
217 { return from_utc(utc_clock::now()); }
219 template<typename _Duration>
221 static utc_time<common_type_t<_Duration, seconds>>
222 to_utc(const gps_time<_Duration>& __t)
224 using _CDur = common_type_t<_Duration, seconds>;
225 return utc_time<_CDur>{__t.time_since_epoch()} + 315964809s;
228 template<typename _Duration>
230 static gps_time<common_type_t<_Duration, seconds>>
231 from_utc(const utc_time<_Duration>& __t)
233 using _CDur = common_type_t<_Duration, seconds>;
234 return gps_time<_CDur>{__t.time_since_epoch()} - 315964809s;
239 template<typename _DestClock, typename _SourceClock>
240 struct clock_time_conversion
243 // Identity conversions
245 template<typename _Clock>
246 struct clock_time_conversion<_Clock, _Clock>
248 template<typename _Duration>
249 time_point<_Clock, _Duration>
250 operator()(const time_point<_Clock, _Duration>& __t) const
255 struct clock_time_conversion<system_clock, system_clock>
257 template<typename _Duration>
259 operator()(const sys_time<_Duration>& __t) const
264 struct clock_time_conversion<utc_clock, utc_clock>
266 template<typename _Duration>
268 operator()(const utc_time<_Duration>& __t) const
272 // Conversions between system_clock and utc_clock
275 struct clock_time_conversion<utc_clock, system_clock>
277 template<typename _Duration>
278 utc_time<common_type_t<_Duration, seconds>>
279 operator()(const sys_time<_Duration>& __t) const
280 { return utc_clock::from_sys(__t); }
284 struct clock_time_conversion<system_clock, utc_clock>
286 template<typename _Duration>
287 sys_time<common_type_t<_Duration, seconds>>
288 operator()(const utc_time<_Duration>& __t) const
289 { return utc_clock::to_sys(__t); }
292 template<typename _Tp, typename _Clock>
293 inline constexpr bool __is_time_point_for_v = false;
295 template<typename _Clock, typename _Duration>
296 inline constexpr bool
297 __is_time_point_for_v<time_point<_Clock, _Duration>, _Clock> = true;
299 // Conversions between system_clock and other clocks
301 template<typename _SourceClock>
302 struct clock_time_conversion<system_clock, _SourceClock>
304 template<typename _Duration, typename _Src = _SourceClock>
306 operator()(const time_point<_SourceClock, _Duration>& __t) const
307 -> decltype(_Src::to_sys(__t))
309 using _Ret = decltype(_SourceClock::to_sys(__t));
310 static_assert(__is_time_point_for_v<_Ret, system_clock>);
311 return _SourceClock::to_sys(__t);
315 template<typename _DestClock>
316 struct clock_time_conversion<_DestClock, system_clock>
318 template<typename _Duration, typename _Dest = _DestClock>
320 operator()(const sys_time<_Duration>& __t) const
321 -> decltype(_Dest::from_sys(__t))
323 using _Ret = decltype(_DestClock::from_sys(__t));
324 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
325 return _DestClock::from_sys(__t);
329 // Conversions between utc_clock and other clocks
331 template<typename _SourceClock>
332 struct clock_time_conversion<utc_clock, _SourceClock>
334 template<typename _Duration, typename _Src = _SourceClock>
336 operator()(const time_point<_SourceClock, _Duration>& __t) const
337 -> decltype(_Src::to_utc(__t))
339 using _Ret = decltype(_SourceClock::to_utc(__t));
340 static_assert(__is_time_point_for_v<_Ret, utc_clock>);
341 return _SourceClock::to_utc(__t);
345 template<typename _DestClock>
346 struct clock_time_conversion<_DestClock, utc_clock>
348 template<typename _Duration, typename _Dest = _DestClock>
350 operator()(const utc_time<_Duration>& __t) const
351 -> decltype(_Dest::from_utc(__t))
353 using _Ret = decltype(_DestClock::from_utc(__t));
354 static_assert(__is_time_point_for_v<_Ret, _DestClock>);
355 return _DestClock::from_utc(__t);
359 /// @cond undocumented
362 template<typename _DestClock, typename _SourceClock, typename _Duration>
363 concept __clock_convs
364 = requires (const time_point<_SourceClock, _Duration>& __t) {
365 clock_time_conversion<_DestClock, _SourceClock>{}(__t);
368 template<typename _DestClock, typename _SourceClock, typename _Duration>
369 concept __clock_convs_sys
370 = requires (const time_point<_SourceClock, _Duration>& __t) {
371 clock_time_conversion<_DestClock, system_clock>{}(
372 clock_time_conversion<system_clock, _SourceClock>{}(__t));
375 template<typename _DestClock, typename _SourceClock, typename _Duration>
376 concept __clock_convs_utc
377 = requires (const time_point<_SourceClock, _Duration>& __t) {
378 clock_time_conversion<_DestClock, utc_clock>{}(
379 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
382 template<typename _DestClock, typename _SourceClock, typename _Duration>
383 concept __clock_convs_sys_utc
384 = requires (const time_point<_SourceClock, _Duration>& __t) {
385 clock_time_conversion<_DestClock, utc_clock>{}(
386 clock_time_conversion<utc_clock, system_clock>{}(
387 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
390 template<typename _DestClock, typename _SourceClock, typename _Duration>
391 concept __clock_convs_utc_sys
392 = requires (const time_point<_SourceClock, _Duration>& __t) {
393 clock_time_conversion<_DestClock, system_clock>{}(
394 clock_time_conversion<system_clock, utc_clock>{}(
395 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
398 } // namespace __detail
401 /// Convert a time point to a different clock.
402 template<typename _DestClock, typename _SourceClock, typename _Duration>
405 clock_cast(const time_point<_SourceClock, _Duration>& __t)
406 requires __detail::__clock_convs<_DestClock, _SourceClock, _Duration>
407 || __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>
408 || __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>
409 || __detail::__clock_convs_sys_utc<_DestClock, _SourceClock, _Duration>
410 || __detail::__clock_convs_utc_sys<_DestClock, _SourceClock, _Duration>
412 constexpr bool __direct
413 = __detail::__clock_convs<_DestClock, _SourceClock, _Duration>;
414 if constexpr (__direct)
416 return clock_time_conversion<_DestClock, _SourceClock>{}(__t);
420 constexpr bool __convert_via_sys_clock
421 = __detail::__clock_convs_sys<_DestClock, _SourceClock, _Duration>;
422 constexpr bool __convert_via_utc_clock
423 = __detail::__clock_convs_utc<_DestClock, _SourceClock, _Duration>;
424 if constexpr (__convert_via_sys_clock)
426 static_assert(!__convert_via_utc_clock,
427 "clock_cast requires a unique best conversion, but "
428 "conversion is possible via system_clock and also via"
430 return clock_time_conversion<_DestClock, system_clock>{}(
431 clock_time_conversion<system_clock, _SourceClock>{}(__t));
433 else if constexpr (__convert_via_utc_clock)
435 return clock_time_conversion<_DestClock, utc_clock>{}(
436 clock_time_conversion<utc_clock, _SourceClock>{}(__t));
440 constexpr bool __convert_via_sys_and_utc_clocks
441 = __detail::__clock_convs_sys_utc<_DestClock,
445 if constexpr (__convert_via_sys_and_utc_clocks)
447 constexpr bool __convert_via_utc_and_sys_clocks
448 = __detail::__clock_convs_utc_sys<_DestClock,
451 static_assert(!__convert_via_utc_and_sys_clocks,
452 "clock_cast requires a unique best conversion, but "
453 "conversion is possible via system_clock followed by "
454 "utc_clock, and also via utc_clock followed by "
456 return clock_time_conversion<_DestClock, utc_clock>{}(
457 clock_time_conversion<utc_clock, system_clock>{}(
458 clock_time_conversion<system_clock, _SourceClock>{}(__t)));
462 return clock_time_conversion<_DestClock, system_clock>{}(
463 clock_time_conversion<system_clock, utc_clock>{}(
464 clock_time_conversion<utc_clock, _SourceClock>{}(__t)));
472 // CLASS DECLARATIONS
477 class weekday_indexed;
480 class month_day_last;
482 class month_weekday_last;
484 class year_month_day;
485 class year_month_day_last;
486 class year_month_weekday;
487 class year_month_weekday_last;
491 explicit last_spec() = default;
493 friend constexpr month_day_last
494 operator/(int __m, last_spec) noexcept;
496 friend constexpr month_day_last
497 operator/(last_spec, int __m) noexcept;
500 inline constexpr last_spec last{};
504 // Helper to __add_modulo and __sub_modulo.
505 template <unsigned __d, typename _Tp>
509 using _Up = make_unsigned_t<_Tp>;
510 auto constexpr __a = _Up(-1) - _Up(255 + __d - 2);
511 auto constexpr __b = _Up(__d * (__a / __d) - 1);
512 // Notice: b <= a - 1 <= _Up(-1) - (255 + d - 1) and b % d = d - 1.
513 return _Up(-1) - __b; // >= 255 + d - 1
516 // Compute the remainder of the Euclidean division of __x + __y divided by
517 // __d without overflowing. Typically, __x <= 255 + d - 1 is sum of
518 // weekday/month with a shift in [0, d - 1] and __y is a duration count.
519 template <unsigned __d, typename _Tp>
521 __add_modulo(unsigned __x, _Tp __y)
523 using _Up = make_unsigned_t<_Tp>;
524 // For __y >= 0, _Up(__y) has the same mathematical value as __y and
525 // this function simply returns (__x + _Up(__y)) % d. Typically, this
526 // doesn't overflow since the range of _Up contains many more positive
527 // values than _Tp's. For __y < 0, _Up(__y) has a mathematical value in
528 // the upper-half range of _Up so that adding a positive value to it
529 // might overflow. Moreover, most likely, _Up(__y) != __y mod d. To
530 // fix both issues we subtract from _Up(__y) an __offset >=
531 // 255 + d - 1 to make room for the addition to __x and shift the modulo
532 // to the correct value.
533 auto const __offset = __y >= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
534 return (__x + _Up(__y) - __offset) % __d;
537 // Similar to __add_modulo but for __x - __y.
538 template <unsigned __d, typename _Tp>
540 __sub_modulo(unsigned __x, _Tp __y)
542 using _Up = make_unsigned_t<_Tp>;
543 auto const __offset = __y <= 0 ? _Up(0) : __modulo_offset<__d, _Tp>();
544 return (__x - _Up(__y) - __offset) % __d;
547 inline constexpr unsigned __days_per_month[12]
548 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
562 day(unsigned __d) noexcept
567 operator++() noexcept
574 operator++(int) noexcept
582 operator--() noexcept
589 operator--(int) noexcept
597 operator+=(const days& __d) noexcept
604 operator-=(const days& __d) noexcept
611 operator unsigned() const noexcept
616 { return 1 <= _M_d && _M_d <= 31; }
618 friend constexpr bool
619 operator==(const day& __x, const day& __y) noexcept
620 { return unsigned{__x} == unsigned{__y}; }
622 friend constexpr strong_ordering
623 operator<=>(const day& __x, const day& __y) noexcept
624 { return unsigned{__x} <=> unsigned{__y}; }
627 operator+(const day& __x, const days& __y) noexcept
628 { return day(unsigned{__x} + __y.count()); }
631 operator+(const days& __x, const day& __y) noexcept
632 { return __y + __x; }
635 operator-(const day& __x, const days& __y) noexcept
636 { return __x + -__y; }
638 friend constexpr days
639 operator-(const day& __x, const day& __y) noexcept
640 { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
642 friend constexpr month_day
643 operator/(const month& __m, const day& __d) noexcept;
645 friend constexpr month_day
646 operator/(int __m, const day& __d) noexcept;
648 friend constexpr month_day
649 operator/(const day& __d, const month& __m) noexcept;
651 friend constexpr month_day
652 operator/(const day& __d, int __m) noexcept;
654 friend constexpr year_month_day
655 operator/(const year_month& __ym, const day& __d) noexcept;
669 month(unsigned __m) noexcept
674 operator++() noexcept
681 operator++(int) noexcept
689 operator--() noexcept
696 operator--(int) noexcept
704 operator+=(const months& __m) noexcept
711 operator-=(const months& __m) noexcept
718 operator unsigned() const noexcept
723 { return 1 <= _M_m && _M_m <= 12; }
725 friend constexpr bool
726 operator==(const month& __x, const month& __y) noexcept
727 { return unsigned{__x} == unsigned{__y}; }
729 friend constexpr strong_ordering
730 operator<=>(const month& __x, const month& __y) noexcept
731 { return unsigned{__x} <=> unsigned{__y}; }
733 friend constexpr month
734 operator+(const month& __x, const months& __y) noexcept
736 // modulo(x + (y - 1), 12) = modulo(x + (y - 1) + 12, 12)
737 // = modulo((x + 11) + y , 12)
738 return month{1 + __detail::__add_modulo<12>(
739 unsigned{__x} + 11, __y.count())};
742 friend constexpr month
743 operator+(const months& __x, const month& __y) noexcept
744 { return __y + __x; }
746 friend constexpr month
747 operator-(const month& __x, const months& __y) noexcept
749 // modulo(x + (-y - 1), 12) = modulo(x + (-y - 1) + 12, 12)
750 // = modulo((x + 11) - y , 12)
751 return month{1 + __detail::__sub_modulo<12>(
752 unsigned{__x} + 11, __y.count())};
755 friend constexpr months
756 operator-(const month& __x, const month& __y) noexcept
758 const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
759 return months{__dm < 0 ? 12 + __dm : __dm};
762 friend constexpr year_month
763 operator/(const year& __y, const month& __m) noexcept;
765 friend constexpr month_day
766 operator/(const month& __m, int __d) noexcept;
768 friend constexpr month_day_last
769 operator/(const month& __m, last_spec) noexcept;
771 friend constexpr month_day_last
772 operator/(last_spec, const month& __m) noexcept;
774 friend constexpr month_weekday
775 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
777 friend constexpr month_weekday
778 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
780 friend constexpr month_weekday_last
781 operator/(const month& __m, const weekday_last& __wdl) noexcept;
783 friend constexpr month_weekday_last
784 operator/(const weekday_last& __wdl, const month& __m) noexcept;
787 inline constexpr month January{1};
788 inline constexpr month February{2};
789 inline constexpr month March{3};
790 inline constexpr month April{4};
791 inline constexpr month May{5};
792 inline constexpr month June{6};
793 inline constexpr month July{7};
794 inline constexpr month August{8};
795 inline constexpr month September{9};
796 inline constexpr month October{10};
797 inline constexpr month November{11};
798 inline constexpr month December{12};
811 year(int __y) noexcept
812 : _M_y{static_cast<short>(__y)}
815 static constexpr year
817 { return year{-32767}; }
819 static constexpr year
821 { return year{32767}; }
824 operator++() noexcept
831 operator++(int) noexcept
839 operator--() noexcept
846 operator--(int) noexcept
854 operator+=(const years& __y) noexcept
861 operator-=(const years& __y) noexcept
868 operator+() const noexcept
872 operator-() const noexcept
873 { return year{-_M_y}; }
876 is_leap() const noexcept
878 // Testing divisibility by 100 first gives better performance [1], i.e.,
879 // return _M_y % 100 == 0 ? _M_y % 400 == 0 : _M_y % 16 == 0;
880 // Furthermore, if _M_y % 100 == 0, then _M_y % 400 == 0 is equivalent
881 // to _M_y % 16 == 0, so we can simplify it to
882 // return _M_y % 100 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #1
883 // Similarly, we can replace 100 with 25 (which is good since
884 // _M_y % 25 == 0 requires one fewer instruction than _M_y % 100 == 0
886 // return _M_y % 25 == 0 ? _M_y % 16 == 0 : _M_y % 4 == 0. // #2
887 // Indeed, first assume _M_y % 4 != 0. Then _M_y % 16 != 0 and hence,
888 // _M_y % 4 == 0 and _M_y % 16 == 0 are both false. Therefore, #2
889 // returns false as it should (regardless of _M_y % 25.) Now assume
890 // _M_y % 4 == 0. In this case, _M_y % 25 == 0 if, and only if,
891 // _M_y % 100 == 0, that is, #1 and #2 are equivalent. Finally, #2 is
893 // return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0.
896 // [1] https://github.com/cassioneri/calendar
897 // [2] https://godbolt.org/z/55G8rn77e
898 // [3] https://gcc.gnu.org/pipermail/libstdc++/2021-June/052815.html
900 return (_M_y & (_M_y % 25 == 0 ? 15 : 3)) == 0;
904 operator int() const noexcept
909 { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
911 friend constexpr bool
912 operator==(const year& __x, const year& __y) noexcept
913 { return int{__x} == int{__y}; }
915 friend constexpr strong_ordering
916 operator<=>(const year& __x, const year& __y) noexcept
917 { return int{__x} <=> int{__y}; }
919 friend constexpr year
920 operator+(const year& __x, const years& __y) noexcept
921 { return year{int{__x} + static_cast<int>(__y.count())}; }
923 friend constexpr year
924 operator+(const years& __x, const year& __y) noexcept
925 { return __y + __x; }
927 friend constexpr year
928 operator-(const year& __x, const years& __y) noexcept
929 { return __x + -__y; }
931 friend constexpr years
932 operator-(const year& __x, const year& __y) noexcept
933 { return years{int{__x} - int{__y}}; }
935 friend constexpr year_month
936 operator/(const year& __y, int __m) noexcept;
938 friend constexpr year_month_day
939 operator/(const year& __y, const month_day& __md) noexcept;
941 friend constexpr year_month_day
942 operator/(const month_day& __md, const year& __y) noexcept;
944 friend constexpr year_month_day_last
945 operator/(const year& __y, const month_day_last& __mdl) noexcept;
947 friend constexpr year_month_day_last
948 operator/(const month_day_last& __mdl, const year& __y) noexcept;
950 friend constexpr year_month_weekday
951 operator/(const year& __y, const month_weekday& __mwd) noexcept;
953 friend constexpr year_month_weekday
954 operator/(const month_weekday& __mwd, const year& __y) noexcept;
956 friend constexpr year_month_weekday_last
957 operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
959 friend constexpr year_month_weekday_last
960 operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
970 static constexpr weekday
971 _S_from_days(const days& __d)
973 return weekday{__detail::__add_modulo<7>(4, __d.count())};
980 weekday(unsigned __wd) noexcept
981 : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
985 weekday(const sys_days& __dp) noexcept
986 : weekday{_S_from_days(__dp.time_since_epoch())}
990 weekday(const local_days& __dp) noexcept
991 : weekday{sys_days{__dp.time_since_epoch()}}
995 operator++() noexcept
1002 operator++(int) noexcept
1010 operator--() noexcept
1017 operator--(int) noexcept
1025 operator+=(const days& __d) noexcept
1027 *this = *this + __d;
1032 operator-=(const days& __d) noexcept
1034 *this = *this - __d;
1039 c_encoding() const noexcept
1043 iso_encoding() const noexcept
1044 { return _M_wd == 0u ? 7u : _M_wd; }
1048 { return _M_wd <= 6; }
1050 constexpr weekday_indexed
1051 operator[](unsigned __index) const noexcept;
1053 constexpr weekday_last
1054 operator[](last_spec) const noexcept;
1056 friend constexpr bool
1057 operator==(const weekday& __x, const weekday& __y) noexcept
1058 { return __x._M_wd == __y._M_wd; }
1060 friend constexpr weekday
1061 operator+(const weekday& __x, const days& __y) noexcept
1063 return weekday{__detail::__add_modulo<7>(__x._M_wd, __y.count())};
1066 friend constexpr weekday
1067 operator+(const days& __x, const weekday& __y) noexcept
1068 { return __y + __x; }
1070 friend constexpr weekday
1071 operator-(const weekday& __x, const days& __y) noexcept
1073 return weekday{__detail::__sub_modulo<7>(__x._M_wd, __y.count())};
1076 friend constexpr days
1077 operator-(const weekday& __x, const weekday& __y) noexcept
1079 const auto __n = __x.c_encoding() - __y.c_encoding();
1080 return static_cast<int>(__n) >= 0 ? days{__n} : days{__n + 7};
1084 inline constexpr weekday Sunday{0};
1085 inline constexpr weekday Monday{1};
1086 inline constexpr weekday Tuesday{2};
1087 inline constexpr weekday Wednesday{3};
1088 inline constexpr weekday Thursday{4};
1089 inline constexpr weekday Friday{5};
1090 inline constexpr weekday Saturday{6};
1094 class weekday_indexed
1097 chrono::weekday _M_wd;
1098 unsigned char _M_index;
1101 weekday_indexed() = default;
1104 weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
1105 : _M_wd(__wd), _M_index(__index)
1108 constexpr chrono::weekday
1109 weekday() const noexcept
1113 index() const noexcept
1114 { return _M_index; };
1118 { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
1120 friend constexpr bool
1121 operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
1122 { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
1124 friend constexpr month_weekday
1125 operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
1127 friend constexpr month_weekday
1128 operator/(int __m, const weekday_indexed& __wdi) noexcept;
1130 friend constexpr month_weekday
1131 operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
1133 friend constexpr month_weekday
1134 operator/(const weekday_indexed& __wdi, int __m) noexcept;
1136 friend constexpr year_month_weekday
1137 operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
1140 constexpr weekday_indexed
1141 weekday::operator[](unsigned __index) const noexcept
1142 { return {*this, __index}; }
1149 chrono::weekday _M_wd;
1153 weekday_last(const chrono::weekday& __wd) noexcept
1157 constexpr chrono::weekday
1158 weekday() const noexcept
1163 { return _M_wd.ok(); }
1165 friend constexpr bool
1166 operator==(const weekday_last& __x, const weekday_last& __y) noexcept
1167 { return __x.weekday() == __y.weekday(); }
1169 friend constexpr month_weekday_last
1170 operator/(int __m, const weekday_last& __wdl) noexcept;
1172 friend constexpr month_weekday_last
1173 operator/(const weekday_last& __wdl, int __m) noexcept;
1175 friend constexpr year_month_weekday_last
1176 operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
1179 constexpr weekday_last
1180 weekday::operator[](last_spec) const noexcept
1181 { return weekday_last{*this}; }
1192 month_day() = default;
1195 month_day(const chrono::month& __m, const chrono::day& __d) noexcept
1196 : _M_m{__m}, _M_d{__d}
1199 constexpr chrono::month
1200 month() const noexcept
1203 constexpr chrono::day
1204 day() const noexcept
1211 && 1u <= unsigned(_M_d)
1212 && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
1215 friend constexpr bool
1216 operator==(const month_day& __x, const month_day& __y) noexcept
1217 { return __x.month() == __y.month() && __x.day() == __y.day(); }
1219 friend constexpr strong_ordering
1220 operator<=>(const month_day& __x, const month_day& __y) noexcept
1223 friend constexpr month_day
1224 operator/(const chrono::month& __m, const chrono::day& __d) noexcept
1225 { return {__m, __d}; }
1227 friend constexpr month_day
1228 operator/(const chrono::month& __m, int __d) noexcept
1229 { return {__m, chrono::day(unsigned(__d))}; }
1231 friend constexpr month_day
1232 operator/(int __m, const chrono::day& __d) noexcept
1233 { return {chrono::month(unsigned(__m)), __d}; }
1235 friend constexpr month_day
1236 operator/(const chrono::day& __d, const chrono::month& __m) noexcept
1237 { return {__m, __d}; }
1239 friend constexpr month_day
1240 operator/(const chrono::day& __d, int __m) noexcept
1241 { return {chrono::month(unsigned(__m)), __d}; }
1243 friend constexpr year_month_day
1244 operator/(int __y, const month_day& __md) noexcept;
1246 friend constexpr year_month_day
1247 operator/(const month_day& __md, int __y) noexcept;
1252 class month_day_last
1259 month_day_last(const chrono::month& __m) noexcept
1263 constexpr chrono::month
1264 month() const noexcept
1269 { return _M_m.ok(); }
1271 friend constexpr bool
1272 operator==(const month_day_last& __x, const month_day_last& __y) noexcept
1273 { return __x.month() == __y.month(); }
1275 friend constexpr strong_ordering
1276 operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
1279 friend constexpr month_day_last
1280 operator/(const chrono::month& __m, last_spec) noexcept
1281 { return month_day_last{__m}; }
1283 friend constexpr month_day_last
1284 operator/(int __m, last_spec) noexcept
1285 { return chrono::month(unsigned(__m)) / last; }
1287 friend constexpr month_day_last
1288 operator/(last_spec, const chrono::month& __m) noexcept
1289 { return __m / last; }
1291 friend constexpr month_day_last
1292 operator/(last_spec, int __m) noexcept
1293 { return __m / last; }
1295 friend constexpr year_month_day_last
1296 operator/(int __y, const month_day_last& __mdl) noexcept;
1298 friend constexpr year_month_day_last
1299 operator/(const month_day_last& __mdl, int __y) noexcept;
1308 chrono::weekday_indexed _M_wdi;
1312 month_weekday(const chrono::month& __m,
1313 const chrono::weekday_indexed& __wdi) noexcept
1314 : _M_m{__m}, _M_wdi{__wdi}
1317 constexpr chrono::month
1318 month() const noexcept
1321 constexpr chrono::weekday_indexed
1322 weekday_indexed() const noexcept
1327 { return _M_m.ok() && _M_wdi.ok(); }
1329 friend constexpr bool
1330 operator==(const month_weekday& __x, const month_weekday& __y) noexcept
1332 return __x.month() == __y.month()
1333 && __x.weekday_indexed() == __y.weekday_indexed();
1336 friend constexpr month_weekday
1337 operator/(const chrono::month& __m,
1338 const chrono::weekday_indexed& __wdi) noexcept
1339 { return {__m, __wdi}; }
1341 friend constexpr month_weekday
1342 operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
1343 { return chrono::month(unsigned(__m)) / __wdi; }
1345 friend constexpr month_weekday
1346 operator/(const chrono::weekday_indexed& __wdi,
1347 const chrono::month& __m) noexcept
1348 { return __m / __wdi; }
1350 friend constexpr month_weekday
1351 operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
1352 { return __m / __wdi; }
1354 friend constexpr year_month_weekday
1355 operator/(int __y, const month_weekday& __mwd) noexcept;
1357 friend constexpr year_month_weekday
1358 operator/(const month_weekday& __mwd, int __y) noexcept;
1361 // MONTH_WEEKDAY_LAST
1363 class month_weekday_last
1367 chrono::weekday_last _M_wdl;
1371 month_weekday_last(const chrono::month& __m,
1372 const chrono::weekday_last& __wdl) noexcept
1373 :_M_m{__m}, _M_wdl{__wdl}
1376 constexpr chrono::month
1377 month() const noexcept
1380 constexpr chrono::weekday_last
1381 weekday_last() const noexcept
1386 { return _M_m.ok() && _M_wdl.ok(); }
1388 friend constexpr bool
1389 operator==(const month_weekday_last& __x,
1390 const month_weekday_last& __y) noexcept
1392 return __x.month() == __y.month()
1393 && __x.weekday_last() == __y.weekday_last();
1396 friend constexpr month_weekday_last
1397 operator/(const chrono::month& __m,
1398 const chrono::weekday_last& __wdl) noexcept
1399 { return {__m, __wdl}; }
1401 friend constexpr month_weekday_last
1402 operator/(int __m, const chrono::weekday_last& __wdl) noexcept
1403 { return chrono::month(unsigned(__m)) / __wdl; }
1405 friend constexpr month_weekday_last
1406 operator/(const chrono::weekday_last& __wdl,
1407 const chrono::month& __m) noexcept
1408 { return __m / __wdl; }
1410 friend constexpr month_weekday_last
1411 operator/(const chrono::weekday_last& __wdl, int __m) noexcept
1412 { return chrono::month(unsigned(__m)) / __wdl; }
1414 friend constexpr year_month_weekday_last
1415 operator/(int __y, const month_weekday_last& __mwdl) noexcept;
1417 friend constexpr year_month_weekday_last
1418 operator/(const month_weekday_last& __mwdl, int __y) noexcept;
1425 // [time.cal.ym], [time.cal.ymd], etc constrain the 'months'-based
1426 // addition/subtraction operator overloads like so:
1428 // Constraints: if the argument supplied by the caller for the months
1429 // parameter is convertible to years, its implicit conversion sequence
1430 // to years is worse than its implicit conversion sequence to months.
1432 // We realize this constraint by templatizing the 'months'-based
1433 // overloads (using a dummy defaulted template parameter), so that
1434 // overload resolution doesn't select the 'months'-based overload unless
1435 // the implicit conversion sequence to 'months' is better than that to
1437 using __months_years_conversion_disambiguator = void;
1447 year_month() = default;
1450 year_month(const chrono::year& __y, const chrono::month& __m) noexcept
1451 : _M_y{__y}, _M_m{__m}
1454 constexpr chrono::year
1455 year() const noexcept
1458 constexpr chrono::month
1459 month() const noexcept
1462 template<typename = __detail::__months_years_conversion_disambiguator>
1463 constexpr year_month&
1464 operator+=(const months& __dm) noexcept
1466 *this = *this + __dm;
1470 template<typename = __detail::__months_years_conversion_disambiguator>
1471 constexpr year_month&
1472 operator-=(const months& __dm) noexcept
1474 *this = *this - __dm;
1478 constexpr year_month&
1479 operator+=(const years& __dy) noexcept
1481 *this = *this + __dy;
1485 constexpr year_month&
1486 operator-=(const years& __dy) noexcept
1488 *this = *this - __dy;
1494 { return _M_y.ok() && _M_m.ok(); }
1496 friend constexpr bool
1497 operator==(const year_month& __x, const year_month& __y) noexcept
1498 { return __x.year() == __y.year() && __x.month() == __y.month(); }
1500 friend constexpr strong_ordering
1501 operator<=>(const year_month& __x, const year_month& __y) noexcept
1504 template<typename = __detail::__months_years_conversion_disambiguator>
1505 friend constexpr year_month
1506 operator+(const year_month& __ym, const months& __dm) noexcept
1509 auto __m = __ym.month() + __dm;
1510 auto __i = int(unsigned(__ym.month())) - 1 + __dm.count();
1512 ? __ym.year() + years{(__i - 11) / 12}
1513 : __ym.year() + years{__i / 12});
1517 template<typename = __detail::__months_years_conversion_disambiguator>
1518 friend constexpr year_month
1519 operator+(const months& __dm, const year_month& __ym) noexcept
1520 { return __ym + __dm; }
1522 template<typename = __detail::__months_years_conversion_disambiguator>
1523 friend constexpr year_month
1524 operator-(const year_month& __ym, const months& __dm) noexcept
1525 { return __ym + -__dm; }
1527 friend constexpr months
1528 operator-(const year_month& __x, const year_month& __y) noexcept
1530 return (__x.year() - __y.year()
1531 + months{static_cast<int>(unsigned{__x.month()})
1532 - static_cast<int>(unsigned{__y.month()})});
1535 friend constexpr year_month
1536 operator+(const year_month& __ym, const years& __dy) noexcept
1537 { return (__ym.year() + __dy) / __ym.month(); }
1539 friend constexpr year_month
1540 operator+(const years& __dy, const year_month& __ym) noexcept
1541 { return __ym + __dy; }
1543 friend constexpr year_month
1544 operator-(const year_month& __ym, const years& __dy) noexcept
1545 { return __ym + -__dy; }
1547 friend constexpr year_month
1548 operator/(const chrono::year& __y, const chrono::month& __m) noexcept
1549 { return {__y, __m}; }
1551 friend constexpr year_month
1552 operator/(const chrono::year& __y, int __m) noexcept
1553 { return {__y, chrono::month(unsigned(__m))}; }
1555 friend constexpr year_month_day
1556 operator/(const year_month& __ym, int __d) noexcept;
1558 friend constexpr year_month_day_last
1559 operator/(const year_month& __ym, last_spec) noexcept;
1564 class year_month_day
1571 static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
1573 constexpr days _M_days_since_epoch() const noexcept;
1576 year_month_day() = default;
1579 year_month_day(const chrono::year& __y, const chrono::month& __m,
1580 const chrono::day& __d) noexcept
1581 : _M_y{__y}, _M_m{__m}, _M_d{__d}
1585 year_month_day(const year_month_day_last& __ymdl) noexcept;
1588 year_month_day(const sys_days& __dp) noexcept
1589 : year_month_day(_S_from_days(__dp.time_since_epoch()))
1593 year_month_day(const local_days& __dp) noexcept
1594 : year_month_day(sys_days{__dp.time_since_epoch()})
1597 template<typename = __detail::__months_years_conversion_disambiguator>
1598 constexpr year_month_day&
1599 operator+=(const months& __m) noexcept
1601 *this = *this + __m;
1605 template<typename = __detail::__months_years_conversion_disambiguator>
1606 constexpr year_month_day&
1607 operator-=(const months& __m) noexcept
1609 *this = *this - __m;
1613 constexpr year_month_day&
1614 operator+=(const years& __y) noexcept
1616 *this = *this + __y;
1620 constexpr year_month_day&
1621 operator-=(const years& __y) noexcept
1623 *this = *this - __y;
1627 constexpr chrono::year
1628 year() const noexcept
1631 constexpr chrono::month
1632 month() const noexcept
1635 constexpr chrono::day
1636 day() const noexcept
1640 operator sys_days() const noexcept
1641 { return sys_days{_M_days_since_epoch()}; }
1644 operator local_days() const noexcept
1645 { return local_days{sys_days{*this}.time_since_epoch()}; }
1647 constexpr bool ok() const noexcept;
1649 friend constexpr bool
1650 operator==(const year_month_day& __x, const year_month_day& __y) noexcept
1652 return __x.year() == __y.year()
1653 && __x.month() == __y.month()
1654 && __x.day() == __y.day();
1657 friend constexpr strong_ordering
1658 operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
1661 template<typename = __detail::__months_years_conversion_disambiguator>
1662 friend constexpr year_month_day
1663 operator+(const year_month_day& __ymd, const months& __dm) noexcept
1664 { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
1666 template<typename = __detail::__months_years_conversion_disambiguator>
1667 friend constexpr year_month_day
1668 operator+(const months& __dm, const year_month_day& __ymd) noexcept
1669 { return __ymd + __dm; }
1671 friend constexpr year_month_day
1672 operator+(const year_month_day& __ymd, const years& __dy) noexcept
1673 { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
1675 friend constexpr year_month_day
1676 operator+(const years& __dy, const year_month_day& __ymd) noexcept
1677 { return __ymd + __dy; }
1679 template<typename = __detail::__months_years_conversion_disambiguator>
1680 friend constexpr year_month_day
1681 operator-(const year_month_day& __ymd, const months& __dm) noexcept
1682 { return __ymd + -__dm; }
1684 friend constexpr year_month_day
1685 operator-(const year_month_day& __ymd, const years& __dy) noexcept
1686 { return __ymd + -__dy; }
1688 friend constexpr year_month_day
1689 operator/(const year_month& __ym, const chrono::day& __d) noexcept
1690 { return {__ym.year(), __ym.month(), __d}; }
1692 friend constexpr year_month_day
1693 operator/(const year_month& __ym, int __d) noexcept
1694 { return __ym / chrono::day{unsigned(__d)}; }
1696 friend constexpr year_month_day
1697 operator/(const chrono::year& __y, const month_day& __md) noexcept
1698 { return __y / __md.month() / __md.day(); }
1700 friend constexpr year_month_day
1701 operator/(int __y, const month_day& __md) noexcept
1702 { return chrono::year{__y} / __md; }
1704 friend constexpr year_month_day
1705 operator/(const month_day& __md, const chrono::year& __y) noexcept
1706 { return __y / __md; }
1708 friend constexpr year_month_day
1709 operator/(const month_day& __md, int __y) noexcept
1710 { return chrono::year(__y) / __md; }
1713 // Construct from days since 1970/01/01.
1714 // Proposition 6.3 of Neri and Schneider,
1715 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1716 // https://arxiv.org/abs/2102.06959
1717 constexpr year_month_day
1718 year_month_day::_S_from_days(const days& __dp) noexcept
1720 constexpr auto __z2 = static_cast<uint32_t>(-1468000);
1721 constexpr auto __r2_e3 = static_cast<uint32_t>(536895458);
1723 const auto __r0 = static_cast<uint32_t>(__dp.count()) + __r2_e3;
1725 const auto __n1 = 4 * __r0 + 3;
1726 const auto __q1 = __n1 / 146097;
1727 const auto __r1 = __n1 % 146097 / 4;
1729 constexpr auto __p32 = static_cast<uint64_t>(1) << 32;
1730 const auto __n2 = 4 * __r1 + 3;
1731 const auto __u2 = static_cast<uint64_t>(2939745) * __n2;
1732 const auto __q2 = static_cast<uint32_t>(__u2 / __p32);
1733 const auto __r2 = static_cast<uint32_t>(__u2 % __p32) / 2939745 / 4;
1735 constexpr auto __p16 = static_cast<uint32_t>(1) << 16;
1736 const auto __n3 = 2141 * __r2 + 197913;
1737 const auto __q3 = __n3 / __p16;
1738 const auto __r3 = __n3 % __p16 / 2141;
1740 const auto __y0 = 100 * __q1 + __q2;
1741 const auto __m0 = __q3;
1742 const auto __d0 = __r3;
1744 const auto __j = __r2 >= 306;
1745 const auto __y1 = __y0 + __j;
1746 const auto __m1 = __j ? __m0 - 12 : __m0;
1747 const auto __d1 = __d0 + 1;
1749 return year_month_day{chrono::year{static_cast<int>(__y1 + __z2)},
1750 chrono::month{__m1}, chrono::day{__d1}};
1753 // Days since 1970/01/01.
1754 // Proposition 6.2 of Neri and Schneider,
1755 // "Euclidean Affine Functions and Applications to Calendar Algorithms".
1756 // https://arxiv.org/abs/2102.06959
1758 year_month_day::_M_days_since_epoch() const noexcept
1760 auto constexpr __z2 = static_cast<uint32_t>(-1468000);
1761 auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
1763 const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
1764 const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
1765 const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
1767 const auto __j = static_cast<uint32_t>(__m1 < 3);
1768 const auto __y0 = __y1 - __j;
1769 const auto __m0 = __j ? __m1 + 12 : __m1;
1770 const auto __d0 = __d1 - 1;
1772 const auto __q1 = __y0 / 100;
1773 const auto __yc = 1461 * __y0 / 4 - __q1 + __q1 / 4;
1774 const auto __mc = (979 *__m0 - 2919) / 32;
1775 const auto __dc = __d0;
1777 return days{static_cast<int32_t>(__yc + __mc + __dc - __r2_e3)};
1780 // YEAR_MONTH_DAY_LAST
1782 class year_month_day_last
1786 chrono::month_day_last _M_mdl;
1790 year_month_day_last(const chrono::year& __y,
1791 const chrono::month_day_last& __mdl) noexcept
1792 : _M_y{__y}, _M_mdl{__mdl}
1795 template<typename = __detail::__months_years_conversion_disambiguator>
1796 constexpr year_month_day_last&
1797 operator+=(const months& __m) noexcept
1799 *this = *this + __m;
1803 template<typename = __detail::__months_years_conversion_disambiguator>
1804 constexpr year_month_day_last&
1805 operator-=(const months& __m) noexcept
1807 *this = *this - __m;
1811 constexpr year_month_day_last&
1812 operator+=(const years& __y) noexcept
1814 *this = *this + __y;
1818 constexpr year_month_day_last&
1819 operator-=(const years& __y) noexcept
1821 *this = *this - __y;
1825 constexpr chrono::year
1826 year() const noexcept
1829 constexpr chrono::month
1830 month() const noexcept
1831 { return _M_mdl.month(); }
1833 constexpr chrono::month_day_last
1834 month_day_last() const noexcept
1837 // Return A day representing the last day of this year, month pair.
1838 constexpr chrono::day
1839 day() const noexcept
1841 const auto __m = static_cast<unsigned>(month());
1843 // The result is unspecified if __m < 1 or __m > 12. Hence, assume
1844 // 1 <= __m <= 12. For __m != 2, day() == 30 or day() == 31 or, in
1845 // other words, day () == 30 | b, where b is in {0, 1}.
1847 // If __m in {1, 3, 4, 5, 6, 7}, then b is 1 if, and only if, __m is
1848 // odd. Hence, b = __m & 1 = (__m ^ 0) & 1.
1850 // If __m in {8, 9, 10, 11, 12}, then b is 1 if, and only if, __m is
1851 // even. Hence, b = (__m ^ 1) & 1.
1853 // Therefore, b = (__m ^ c) & 1, where c = 0, if __m < 8, or c = 1 if
1854 // __m >= 8, that is, c = __m >> 3.
1856 // Since 30 = (11110)_2 and __m <= 31 = (11111)_2, the "& 1" in b's
1857 // calculation is unnecessary.
1859 // The performance of this implementation does not depend on look-up
1860 // tables being on the L1 cache.
1861 return chrono::day{__m != 2 ? (__m ^ (__m >> 3)) | 30
1862 : _M_y.is_leap() ? 29 : 28};
1866 operator sys_days() const noexcept
1867 { return sys_days{year() / month() / day()}; }
1870 operator local_days() const noexcept
1871 { return local_days{sys_days{*this}.time_since_epoch()}; }
1875 { return _M_y.ok() && _M_mdl.ok(); }
1877 friend constexpr bool
1878 operator==(const year_month_day_last& __x,
1879 const year_month_day_last& __y) noexcept
1881 return __x.year() == __y.year()
1882 && __x.month_day_last() == __y.month_day_last();
1885 friend constexpr strong_ordering
1886 operator<=>(const year_month_day_last& __x,
1887 const year_month_day_last& __y) noexcept
1890 template<typename = __detail::__months_years_conversion_disambiguator>
1891 friend constexpr year_month_day_last
1892 operator+(const year_month_day_last& __ymdl,
1893 const months& __dm) noexcept
1894 { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
1896 template<typename = __detail::__months_years_conversion_disambiguator>
1897 friend constexpr year_month_day_last
1898 operator+(const months& __dm,
1899 const year_month_day_last& __ymdl) noexcept
1900 { return __ymdl + __dm; }
1902 template<typename = __detail::__months_years_conversion_disambiguator>
1903 friend constexpr year_month_day_last
1904 operator-(const year_month_day_last& __ymdl,
1905 const months& __dm) noexcept
1906 { return __ymdl + -__dm; }
1908 friend constexpr year_month_day_last
1909 operator+(const year_month_day_last& __ymdl,
1910 const years& __dy) noexcept
1911 { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
1913 friend constexpr year_month_day_last
1914 operator+(const years& __dy,
1915 const year_month_day_last& __ymdl) noexcept
1916 { return __ymdl + __dy; }
1918 friend constexpr year_month_day_last
1919 operator-(const year_month_day_last& __ymdl,
1920 const years& __dy) noexcept
1921 { return __ymdl + -__dy; }
1923 friend constexpr year_month_day_last
1924 operator/(const year_month& __ym, last_spec) noexcept
1925 { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
1927 friend constexpr year_month_day_last
1928 operator/(const chrono::year& __y,
1929 const chrono::month_day_last& __mdl) noexcept
1930 { return {__y, __mdl}; }
1932 friend constexpr year_month_day_last
1933 operator/(int __y, const chrono::month_day_last& __mdl) noexcept
1934 { return chrono::year(__y) / __mdl; }
1936 friend constexpr year_month_day_last
1937 operator/(const chrono::month_day_last& __mdl,
1938 const chrono::year& __y) noexcept
1939 { return __y / __mdl; }
1941 friend constexpr year_month_day_last
1942 operator/(const chrono::month_day_last& __mdl, int __y) noexcept
1943 { return chrono::year(__y) / __mdl; }
1946 // year_month_day ctor from year_month_day_last
1948 year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
1949 : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
1953 year_month_day::ok() const noexcept
1955 if (!_M_y.ok() || !_M_m.ok())
1957 return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
1960 // YEAR_MONTH_WEEKDAY
1962 class year_month_weekday
1967 chrono::weekday_indexed _M_wdi;
1969 static constexpr year_month_weekday
1970 _S_from_sys_days(const sys_days& __dp)
1972 year_month_day __ymd{__dp};
1973 chrono::weekday __wd{__dp};
1974 auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
1975 return {__ymd.year(), __ymd.month(), __index};
1979 year_month_weekday() = default;
1982 year_month_weekday(const chrono::year& __y, const chrono::month& __m,
1983 const chrono::weekday_indexed& __wdi) noexcept
1984 : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
1988 year_month_weekday(const sys_days& __dp) noexcept
1989 : year_month_weekday{_S_from_sys_days(__dp)}
1993 year_month_weekday(const local_days& __dp) noexcept
1994 : year_month_weekday{sys_days{__dp.time_since_epoch()}}
1997 template<typename = __detail::__months_years_conversion_disambiguator>
1998 constexpr year_month_weekday&
1999 operator+=(const months& __m) noexcept
2001 *this = *this + __m;
2005 template<typename = __detail::__months_years_conversion_disambiguator>
2006 constexpr year_month_weekday&
2007 operator-=(const months& __m) noexcept
2009 *this = *this - __m;
2013 constexpr year_month_weekday&
2014 operator+=(const years& __y) noexcept
2016 *this = *this + __y;
2020 constexpr year_month_weekday&
2021 operator-=(const years& __y) noexcept
2023 *this = *this - __y;
2027 constexpr chrono::year
2028 year() const noexcept
2031 constexpr chrono::month
2032 month() const noexcept
2035 constexpr chrono::weekday
2036 weekday() const noexcept
2037 { return _M_wdi.weekday(); }
2040 index() const noexcept
2041 { return _M_wdi.index(); }
2043 constexpr chrono::weekday_indexed
2044 weekday_indexed() const noexcept
2048 operator sys_days() const noexcept
2050 auto __d = sys_days{year() / month() / 1};
2051 return __d + (weekday() - chrono::weekday(__d)
2052 + days{(static_cast<int>(index())-1)*7});
2056 operator local_days() const noexcept
2057 { return local_days{sys_days{*this}.time_since_epoch()}; }
2062 if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
2064 if (_M_wdi.index() <= 4)
2066 days __d = (_M_wdi.weekday()
2067 - chrono::weekday{sys_days{_M_y / _M_m / 1}}
2068 + days((_M_wdi.index()-1)*7 + 1));
2069 __glibcxx_assert(__d.count() >= 1);
2070 return (unsigned)__d.count() <= (unsigned)(_M_y / _M_m / last).day();
2073 friend constexpr bool
2074 operator==(const year_month_weekday& __x,
2075 const year_month_weekday& __y) noexcept
2077 return __x.year() == __y.year()
2078 && __x.month() == __y.month()
2079 && __x.weekday_indexed() == __y.weekday_indexed();
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
2086 return ((__ymwd.year() / __ymwd.month() + __dm)
2087 / __ymwd.weekday_indexed());
2090 template<typename = __detail::__months_years_conversion_disambiguator>
2091 friend constexpr year_month_weekday
2092 operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
2093 { return __ymwd + __dm; }
2095 friend constexpr year_month_weekday
2096 operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
2097 { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
2099 friend constexpr year_month_weekday
2100 operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
2101 { return __ymwd + __dy; }
2103 template<typename = __detail::__months_years_conversion_disambiguator>
2104 friend constexpr year_month_weekday
2105 operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
2106 { return __ymwd + -__dm; }
2108 friend constexpr year_month_weekday
2109 operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
2110 { return __ymwd + -__dy; }
2112 friend constexpr year_month_weekday
2113 operator/(const year_month& __ym,
2114 const chrono::weekday_indexed& __wdi) noexcept
2115 { return {__ym.year(), __ym.month(), __wdi}; }
2117 friend constexpr year_month_weekday
2118 operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
2119 { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
2121 friend constexpr year_month_weekday
2122 operator/(int __y, const month_weekday& __mwd) noexcept
2123 { return chrono::year(__y) / __mwd; }
2125 friend constexpr year_month_weekday
2126 operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
2127 { return __y / __mwd; }
2129 friend constexpr year_month_weekday
2130 operator/(const month_weekday& __mwd, int __y) noexcept
2131 { return chrono::year(__y) / __mwd; }
2134 // YEAR_MONTH_WEEKDAY_LAST
2136 class year_month_weekday_last
2141 chrono::weekday_last _M_wdl;
2145 year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
2146 const chrono::weekday_last& __wdl) noexcept
2147 : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
2150 template<typename = __detail::__months_years_conversion_disambiguator>
2151 constexpr year_month_weekday_last&
2152 operator+=(const months& __m) noexcept
2154 *this = *this + __m;
2158 template<typename = __detail::__months_years_conversion_disambiguator>
2159 constexpr year_month_weekday_last&
2160 operator-=(const months& __m) noexcept
2162 *this = *this - __m;
2166 constexpr year_month_weekday_last&
2167 operator+=(const years& __y) noexcept
2169 *this = *this + __y;
2173 constexpr year_month_weekday_last&
2174 operator-=(const years& __y) noexcept
2176 *this = *this - __y;
2180 constexpr chrono::year
2181 year() const noexcept
2184 constexpr chrono::month
2185 month() const noexcept
2188 constexpr chrono::weekday
2189 weekday() const noexcept
2190 { return _M_wdl.weekday(); }
2192 constexpr chrono::weekday_last
2193 weekday_last() const noexcept
2197 operator sys_days() const noexcept
2199 const auto __d = sys_days{_M_y / _M_m / last};
2200 return sys_days{(__d - (chrono::weekday{__d}
2201 - _M_wdl.weekday())).time_since_epoch()};
2205 operator local_days() const noexcept
2206 { return local_days{sys_days{*this}.time_since_epoch()}; }
2210 { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
2212 friend constexpr bool
2213 operator==(const year_month_weekday_last& __x,
2214 const year_month_weekday_last& __y) noexcept
2216 return __x.year() == __y.year()
2217 && __x.month() == __y.month()
2218 && __x.weekday_last() == __y.weekday_last();
2221 template<typename = __detail::__months_years_conversion_disambiguator>
2222 friend constexpr year_month_weekday_last
2223 operator+(const year_month_weekday_last& __ymwdl,
2224 const months& __dm) noexcept
2226 return ((__ymwdl.year() / __ymwdl.month() + __dm)
2227 / __ymwdl.weekday_last());
2230 template<typename = __detail::__months_years_conversion_disambiguator>
2231 friend constexpr year_month_weekday_last
2232 operator+(const months& __dm,
2233 const year_month_weekday_last& __ymwdl) noexcept
2234 { return __ymwdl + __dm; }
2236 friend constexpr year_month_weekday_last
2237 operator+(const year_month_weekday_last& __ymwdl,
2238 const years& __dy) noexcept
2239 { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
2241 friend constexpr year_month_weekday_last
2242 operator+(const years& __dy,
2243 const year_month_weekday_last& __ymwdl) noexcept
2244 { return __ymwdl + __dy; }
2246 template<typename = __detail::__months_years_conversion_disambiguator>
2247 friend constexpr year_month_weekday_last
2248 operator-(const year_month_weekday_last& __ymwdl,
2249 const months& __dm) noexcept
2250 { return __ymwdl + -__dm; }
2252 friend constexpr year_month_weekday_last
2253 operator-(const year_month_weekday_last& __ymwdl,
2254 const years& __dy) noexcept
2255 { return __ymwdl + -__dy; }
2257 friend constexpr year_month_weekday_last
2258 operator/(const year_month& __ym,
2259 const chrono::weekday_last& __wdl) noexcept
2260 { return {__ym.year(), __ym.month(), __wdl}; }
2262 friend constexpr year_month_weekday_last
2263 operator/(const chrono::year& __y,
2264 const chrono::month_weekday_last& __mwdl) noexcept
2265 { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
2267 friend constexpr year_month_weekday_last
2268 operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
2269 { return chrono::year(__y) / __mwdl; }
2271 friend constexpr year_month_weekday_last
2272 operator/(const chrono::month_weekday_last& __mwdl,
2273 const chrono::year& __y) noexcept
2274 { return __y / __mwdl; }
2276 friend constexpr year_month_weekday_last
2277 operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
2278 { return chrono::year(__y) / __mwdl; }
2283 /// @cond undocumented
2287 __pow10(unsigned __n)
2295 template<typename _Duration> struct __utc_leap_second;
2299 /** Utility for splitting a duration into hours, minutes, and seconds
2301 * This is a convenience type that provides accessors for the constituent
2302 * parts (hours, minutes, seconds and subseconds) of a duration.
2306 template<typename _Duration>
2309 static_assert( __is_duration<_Duration>::value );
2312 static consteval int
2313 _S_fractional_width()
2315 auto __den = _Duration::period::den;
2316 const int __multiplicity_2 = std::__countr_zero((uintmax_t)__den);
2317 __den >>= __multiplicity_2;
2318 int __multiplicity_5 = 0;
2319 while ((__den % 5) == 0)
2327 int __width = (__multiplicity_2 > __multiplicity_5
2328 ? __multiplicity_2 : __multiplicity_5);
2335 hh_mm_ss(_Duration __d, bool __is_neg)
2336 : _M_h (duration_cast<chrono::hours>(__d)),
2337 _M_m (duration_cast<chrono::minutes>(__d - hours())),
2338 _M_s (duration_cast<chrono::seconds>(__d - hours() - minutes())),
2341 auto __ss = __d - hours() - minutes() - seconds();
2342 if constexpr (treat_as_floating_point_v<typename precision::rep>)
2343 _M_ss._M_r = __ss.count();
2344 else if constexpr (precision::period::den != 1)
2345 _M_ss._M_r = duration_cast<precision>(__ss).count();
2348 static constexpr _Duration
2349 _S_abs(_Duration __d)
2351 if constexpr (numeric_limits<typename _Duration::rep>::is_signed)
2352 return chrono::abs(__d);
2358 static constexpr unsigned fractional_width = {_S_fractional_width()};
2361 = duration<common_type_t<typename _Duration::rep,
2362 chrono::seconds::rep>,
2363 ratio<1, __detail::__pow10(fractional_width)>>;
2365 constexpr hh_mm_ss() noexcept = default;
2368 hh_mm_ss(_Duration __d)
2369 : hh_mm_ss(_S_abs(__d), __d < _Duration::zero())
2373 is_negative() const noexcept
2375 if constexpr (!_S_is_unsigned)
2381 constexpr chrono::hours
2382 hours() const noexcept
2385 constexpr chrono::minutes
2386 minutes() const noexcept
2389 constexpr chrono::seconds
2390 seconds() const noexcept
2394 subseconds() const noexcept
2395 { return static_cast<precision>(_M_ss); }
2398 operator precision() const noexcept
2399 { return to_duration(); }
2402 to_duration() const noexcept
2404 if constexpr (!_S_is_unsigned)
2406 return -(_M_h + _M_m + _M_s + subseconds());
2407 return _M_h + _M_m + _M_s + subseconds();
2411 static constexpr bool _S_is_unsigned
2412 = __and_v<is_integral<typename _Duration::rep>,
2413 is_unsigned<typename _Duration::rep>>;
2415 template<typename _Ratio>
2416 using __byte_duration = duration<unsigned char, _Ratio>;
2418 // The type of the _M_ss member that holds the subsecond precision.
2419 template<typename _Dur>
2422 typename _Dur::rep _M_r{};
2425 operator _Dur() const noexcept
2426 { return _Dur(_M_r); }
2429 // An empty class if this precision doesn't need subseconds.
2430 template<typename _Rep>
2431 requires (!treat_as_floating_point_v<_Rep>)
2432 struct __subseconds<duration<_Rep, ratio<1>>>
2435 operator duration<_Rep, ratio<1>>() const noexcept
2439 template<typename _Rep, typename _Period>
2440 requires (!treat_as_floating_point_v<_Rep>)
2441 && ratio_less_v<_Period, ratio<1, 1>>
2442 && ratio_greater_equal_v<_Period, ratio<1, 250>>
2443 struct __subseconds<duration<_Rep, _Period>>
2445 unsigned char _M_r{};
2448 operator duration<_Rep, _Period>() const noexcept
2449 { return duration<_Rep, _Period>(_M_r); }
2452 template<typename _Rep, typename _Period>
2453 requires (!treat_as_floating_point_v<_Rep>)
2454 && ratio_less_v<_Period, ratio<1, 250>>
2455 && ratio_greater_equal_v<_Period, ratio<1, 4000000000>>
2456 struct __subseconds<duration<_Rep, _Period>>
2458 uint_least32_t _M_r{};
2461 operator duration<_Rep, _Period>() const noexcept
2462 { return duration<_Rep, _Period>(_M_r); }
2465 chrono::hours _M_h{};
2466 __byte_duration<ratio<60>> _M_m{};
2467 __byte_duration<ratio<1>> _M_s{};
2469 __subseconds<precision> _M_ss{};
2471 template<typename> friend struct __detail::__utc_leap_second;
2474 /// @cond undocumented
2477 // Represents a time that is within a leap second insertion.
2478 template<typename _Duration>
2479 struct __utc_leap_second
2482 __utc_leap_second(const sys_time<_Duration>& __s)
2483 : _M_date(chrono::floor<days>(__s)), _M_time(__s - _M_date)
2489 hh_mm_ss<common_type_t<_Duration, days>> _M_time;
2494 // 12/24 HOURS FUNCTIONS
2497 is_am(const hours& __h) noexcept
2498 { return 0h <= __h && __h <= 11h; }
2501 is_pm(const hours& __h) noexcept
2502 { return 12h <= __h && __h <= 23h; }
2505 make12(const hours& __h) noexcept
2515 make24(const hours& __h, bool __is_pm) noexcept
2533 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
2534 // C++20 [time.zones] Time zones
2549 static constexpr int unique = 0;
2550 static constexpr int nonexistent = 1;
2551 static constexpr int ambiguous = 2;
2558 class nonexistent_local_time : public runtime_error
2561 template<typename _Duration>
2562 nonexistent_local_time(const local_time<_Duration>& __tp,
2563 const local_info& __i)
2564 : runtime_error(_S_make_what_str(__tp, __i))
2565 { __glibcxx_assert(__i.result == local_info::nonexistent); }
2568 template<typename _Duration>
2570 _S_make_what_str(const local_time<_Duration>& __tp,
2571 const local_info& __i)
2573 std::ostringstream __os;
2574 __os << __tp << " is in a gap between\n"
2575 << local_seconds(__i.first.end.time_since_epoch())
2576 + __i.first.offset << ' ' << __i.first.abbrev << " and\n"
2577 << local_seconds(__i.second.begin.time_since_epoch())
2578 + __i.second.offset << ' ' << __i.second.abbrev
2579 << " which are both equivalent to\n"
2580 << __i.first.end << " UTC";
2581 return std::move(__os).str();
2585 class ambiguous_local_time : public runtime_error
2588 template<typename _Duration>
2589 ambiguous_local_time(const local_time<_Duration>& __tp,
2590 const local_info& __i)
2591 : runtime_error(_S_make_what_str(__tp, __i))
2592 { __glibcxx_assert(__i.result == local_info::ambiguous); }
2595 template<typename _Duration>
2597 _S_make_what_str(const local_time<_Duration>& __tp,
2598 const local_info& __i)
2600 std::ostringstream __os;
2601 __os << __tp << " is ambiguous. It could be\n"
2602 << __tp << ' ' << __i.first.abbrev << " == "
2603 << __tp - __i.first.offset << " UTC or\n"
2604 << __tp << ' ' << __i.second.abbrev << " == "
2605 << __tp - __i.second.offset << " UTC";
2606 return std::move(__os).str();
2610 template<typename _Duration>
2612 __throw_bad_local_time(const local_time<_Duration>& __tp,
2613 const local_info& __i)
2615 #if __cpp_exceptions
2616 if (__i.result == local_info::nonexistent)
2617 throw nonexistent_local_time(__tp, __i);
2618 throw ambiguous_local_time(__tp, __i);
2624 enum class choose { earliest, latest };
2629 time_zone(time_zone&&) = default;
2630 time_zone& operator=(time_zone&&) = default;
2635 string_view name() const noexcept { return _M_name; }
2637 template<typename _Duration>
2639 get_info(const sys_time<_Duration>& __st) const
2640 { return _M_get_sys_info(chrono::floor<seconds>(__st)); }
2642 template<typename _Duration>
2644 get_info(const local_time<_Duration>& __tp) const
2645 { return _M_get_local_info(chrono::floor<seconds>(__tp)); }
2647 template<typename _Duration>
2648 sys_time<common_type_t<_Duration, seconds>>
2649 to_sys(const local_time<_Duration>& __tp) const
2651 local_info __info = get_info(__tp);
2653 if (__info.result != local_info::unique)
2654 __throw_bad_local_time(__tp, __info);
2656 return sys_time<_Duration>(__tp.time_since_epoch())
2657 - __info.first.offset;
2660 template<typename _Duration>
2661 sys_time<common_type_t<_Duration, seconds>>
2662 to_sys(const local_time<_Duration>& __tp, choose __z) const
2664 local_info __info = get_info(__tp);
2666 if (__info.result == local_info::nonexistent)
2667 return __info.first.end; // Last second of the previous sys_info.
2669 sys_time<_Duration> __st(__tp.time_since_epoch());
2671 if (__info.result == local_info::ambiguous && __z == choose::latest)
2672 return __st - __info.second.offset; // Time in the later sys_info.
2673 // else if __z == earliest, use __info.first.offset as below:
2675 return __st - __info.first.offset;
2678 template<typename _Duration>
2679 local_time<common_type_t<_Duration, seconds>>
2680 to_local(const sys_time<_Duration>& __tp) const
2682 auto __d = (__tp + get_info(__tp).offset).time_since_epoch();
2683 return local_time<common_type_t<_Duration, seconds>>(__d);
2686 [[nodiscard]] friend bool
2687 operator==(const time_zone& __x, const time_zone& __y) noexcept
2688 { return __x._M_name == __y._M_name; }
2690 [[nodiscard]] friend strong_ordering
2691 operator<=>(const time_zone& __x, const time_zone& __y) noexcept
2692 { return __x._M_name <=> __y._M_name; }
2695 sys_info _M_get_sys_info(sys_seconds) const;
2696 local_info _M_get_local_info(local_seconds) const;
2698 friend const tzdb& reload_tzdb();
2700 friend class tzdb_list;
2704 explicit time_zone(unique_ptr<_Impl> __p);
2706 unique_ptr<_Impl> _M_impl;
2709 const time_zone* locate_zone(string_view __tz_name);
2710 const time_zone* current_zone();
2712 /** The list of `chrono::tzdb` objects
2714 * A single object of this type is constructed by the C++ runtime,
2715 * and can be accessed by calling `chrono::get_tzdb_list()`.
2717 * The front of the list is the current `tzdb` object and can be accessed
2718 * via `chrono::get_tzdb_list().front()` or `chrono::get_tzdb()` or
2719 * `*chrono::get_tzdb_list().begin()`.
2721 * The `chrono::reload_tzdb()` function will check for a newer version
2722 * and if found, insert it at the front of the list.
2731 tzdb_list(const tzdb_list&) = delete;
2732 tzdb_list& operator=(const tzdb_list&) = delete;
2734 /** An iterator into the `tzdb_list`
2736 * As a extension, in libstdc++ each `tzdb` is reference-counted
2737 * and the `const_iterator` type shares ownership of the object it
2738 * refers to. This ensures that a `tzdb` erased from the list will
2739 * not be destroyed while there is an iterator that refers to it.
2741 class const_iterator
2744 using value_type = tzdb;
2745 using reference = const tzdb&;
2746 using pointer = const tzdb*;
2747 using difference_type = ptrdiff_t;
2748 using iterator_category = forward_iterator_tag;
2750 constexpr const_iterator() = default;
2751 const_iterator(const const_iterator&) = default;
2752 const_iterator(const_iterator&&) = default;
2753 const_iterator& operator=(const const_iterator&) = default;
2754 const_iterator& operator=(const_iterator&&) = default;
2756 reference operator*() const noexcept;
2757 pointer operator->() const noexcept { return &**this; }
2758 const_iterator& operator++();
2759 const_iterator operator++(int);
2761 bool operator==(const const_iterator&) const noexcept = default;
2764 explicit const_iterator(const shared_ptr<_Node>&) noexcept;
2766 friend class tzdb_list;
2768 shared_ptr<_Node> _M_node;
2769 void* _M_reserved = nullptr;
2772 /** Access the current `tzdb` at the front of the list.
2774 * This returns a reference to the same object as `chrono::get_tzdb()`.
2776 * @returns A reference to the current tzdb object.
2779 const tzdb& front() const noexcept;
2781 /** Remove the tzdb object _after_ the one the iterator refers to.
2783 * Calling this function concurrently with any of `front()`, `begin()`,
2784 * or `end()` does not cause a data race, but in general this function
2785 * is not thread-safe. The behaviour may be undefined if erasing an
2786 * element from the list while another thread is calling the same
2787 * function, or incrementing an iterator into the list, or accessing
2788 * the element being erased (unless it is accessed through an iterator).
2790 * @param __p A dereferenceable iterator.
2791 * @returns An iterator the element after the one that was erased
2792 * (or `end()` if there is no such element).
2795 const_iterator erase_after(const_iterator __p);
2797 const_iterator begin() const noexcept;
2798 const_iterator end() const noexcept { return {}; }
2799 const_iterator cbegin() const noexcept { return begin(); }
2800 const_iterator cend() const noexcept { return end(); }
2803 constexpr explicit tzdb_list(nullptr_t);
2805 friend tzdb_list& get_tzdb_list();
2806 friend const tzdb& get_tzdb();
2807 friend const tzdb& reload_tzdb();
2809 friend class leap_second;
2810 friend struct time_zone::_Impl;
2811 friend class time_zone_link;
2814 class time_zone_link
2817 time_zone_link(time_zone_link&&) = default;
2818 time_zone_link& operator=(time_zone_link&&) = default;
2820 string_view name() const noexcept { return _M_name; }
2821 string_view target() const noexcept { return _M_target; }
2824 operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept
2825 { return __x.name() == __y.name(); }
2827 friend strong_ordering
2828 operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept
2829 { return __x.name() <=> __y.name(); }
2832 friend const tzdb& reload_tzdb();
2833 friend struct tzdb_list::_Node;
2835 explicit time_zone_link(nullptr_t) { }
2844 leap_second(const leap_second&) = default;
2845 leap_second& operator=(const leap_second&) = default;
2848 constexpr sys_seconds
2849 date() const noexcept
2851 if (_M_s >= _M_s.zero()) [[likely]]
2852 return sys_seconds(_M_s);
2853 return sys_seconds(-_M_s);
2858 value() const noexcept
2860 if (_M_s >= _M_s.zero()) [[likely]]
2865 // This can be defaulted because the database will never contain two
2866 // leap_second objects with the same date but different signs.
2867 [[nodiscard]] friend constexpr bool
2868 operator==(const leap_second&, const leap_second&) noexcept = default;
2870 [[nodiscard]] friend constexpr strong_ordering
2871 operator<=>(const leap_second& __x, const leap_second& __y) noexcept
2872 { return __x.date() <=> __y.date(); }
2874 template<typename _Duration>
2875 [[nodiscard]] friend constexpr bool
2876 operator==(const leap_second& __x,
2877 const sys_time<_Duration>& __y) noexcept
2878 { return __x.date() == __y; }
2880 template<typename _Duration>
2881 [[nodiscard]] friend constexpr bool
2882 operator<(const leap_second& __x,
2883 const sys_time<_Duration>& __y) noexcept
2884 { return __x.date() < __y; }
2886 template<typename _Duration>
2887 [[nodiscard]] friend constexpr bool
2888 operator<(const sys_time<_Duration>& __x,
2889 const leap_second& __y) noexcept
2890 { return __x < __y.date(); }
2892 template<typename _Duration>
2893 [[nodiscard]] friend constexpr bool
2894 operator>(const leap_second& __x,
2895 const sys_time<_Duration>& __y) noexcept
2896 { return __y < __x.date(); }
2898 template<typename _Duration>
2899 [[nodiscard]] friend constexpr bool
2900 operator>(const sys_time<_Duration>& __x,
2901 const leap_second& __y) noexcept
2902 { return __y.date() < __x; }
2904 template<typename _Duration>
2905 [[nodiscard]] friend constexpr bool
2906 operator<=(const leap_second& __x,
2907 const sys_time<_Duration>& __y) noexcept
2908 { return !(__y < __x.date()); }
2910 template<typename _Duration>
2911 [[nodiscard]] friend constexpr bool
2912 operator<=(const sys_time<_Duration>& __x,
2913 const leap_second& __y) noexcept
2914 { return !(__y.date() < __x); }
2916 template<typename _Duration>
2917 [[nodiscard]] friend constexpr bool
2918 operator>=(const leap_second& __x,
2919 const sys_time<_Duration>& __y) noexcept
2920 { return !(__x.date() < __y); }
2922 template<typename _Duration>
2923 [[nodiscard]] friend constexpr bool
2924 operator>=(const sys_time<_Duration>& __x,
2925 const leap_second& __y) noexcept
2926 { return !(__x < __y.date()); }
2928 template<three_way_comparable_with<seconds> _Duration>
2929 [[nodiscard]] friend constexpr auto
2930 operator<=>(const leap_second& __x,
2931 const sys_time<_Duration>& __y) noexcept
2932 { return __x.date() <=> __y; }
2935 explicit leap_second(seconds::rep __s) : _M_s(__s) { }
2937 friend struct tzdb_list::_Node;
2939 friend const tzdb& reload_tzdb();
2941 template<typename _Duration>
2942 friend leap_second_info
2943 get_leap_second_info(const utc_time<_Duration>&);
2945 seconds _M_s; // == date().time_since_epoch() * value().count()
2948 template<class _Tp> struct zoned_traits { };
2951 struct zoned_traits<const time_zone*>
2953 static const time_zone*
2955 { return std::chrono::locate_zone("UTC"); }
2957 static const time_zone*
2958 locate_zone(string_view __name)
2959 { return std::chrono::locate_zone(__name); }
2965 _GLIBCXX_STD_C::vector<time_zone> zones;
2966 _GLIBCXX_STD_C::vector<time_zone_link> links;
2967 _GLIBCXX_STD_C::vector<leap_second> leap_seconds;
2970 locate_zone(string_view __tz_name) const;
2973 current_zone() const;
2976 friend const tzdb& reload_tzdb();
2977 friend class time_zone;
2978 friend struct tzdb_list::_Node;
2981 tzdb_list& get_tzdb_list();
2982 const tzdb& get_tzdb();
2984 const tzdb& reload_tzdb();
2985 string remote_version();
2987 template<typename _Duration, typename _TimeZonePtr = const time_zone*>
2990 static_assert(__is_duration_v<_Duration>);
2992 using _Traits = zoned_traits<_TimeZonePtr>;
2994 // Every constructor that accepts a string_view as its first parameter
2995 // does not participate in class template argument deduction.
2996 using string_view = type_identity_t<std::string_view>;
2999 using duration = common_type_t<_Duration, seconds>;
3001 zoned_time() requires requires { _Traits::default_zone(); }
3004 zoned_time(const zoned_time&) = default;
3005 zoned_time& operator=(const zoned_time&) = default;
3007 zoned_time(const sys_time<_Duration>& __st)
3008 requires requires { _Traits::default_zone(); }
3013 zoned_time(_TimeZonePtr __z) : _M_zone(std::move(__z)) { }
3016 zoned_time(string_view __name)
3018 _TimeZonePtr{_Traits::locate_zone(std::string_view{})};
3020 : _M_zone(_Traits::locate_zone(__name))
3023 template<typename _Duration2>
3024 zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt)
3025 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3026 : _M_zone(__zt._M_zone), _M_tp(__zt._M_tp)
3029 zoned_time(_TimeZonePtr __z, const sys_time<_Duration>& __st)
3030 : _M_zone(std::move(__z)), _M_tp(__st)
3033 zoned_time(string_view __name, const sys_time<_Duration>& __st)
3034 : zoned_time(_Traits::locate_zone(__name), __st)
3037 zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp)
3039 { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3041 : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp))
3044 zoned_time(string_view __name, const local_time<_Duration>& __tp)
3045 requires requires (_TimeZonePtr __z) {
3046 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3047 { __z->to_sys(__tp) } -> convertible_to<sys_time<_Duration>>;
3049 : zoned_time(_Traits::locate_zone(__name), __tp)
3052 zoned_time(_TimeZonePtr __z, const local_time<_Duration>& __tp,
3055 { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3057 : _M_zone(std::move(__z)), _M_tp(_M_zone->to_sys(__tp, __c))
3060 zoned_time(string_view __name, const local_time<_Duration>& __tp,
3062 requires requires (_TimeZonePtr __z) {
3063 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3064 { __z->to_sys(__tp, __c) } -> convertible_to<sys_time<_Duration>>;
3066 : _M_zone(_Traits::locate_zone(__name)),
3067 _M_tp(_M_zone->to_sys(__tp, __c))
3070 template<typename _Duration2, typename _TimeZonePtr2>
3071 zoned_time(_TimeZonePtr __z,
3072 const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3073 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3074 : _M_zone(__z), _M_tp(__zt._M_tp)
3077 template<typename _Duration2, typename _TimeZonePtr2>
3078 zoned_time(_TimeZonePtr __z,
3079 const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3081 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3082 : _M_zone(__z), _M_tp(__zt._M_tp)
3085 template<typename _Duration2, typename _TimeZonePtr2>
3086 zoned_time(string_view __name,
3087 const zoned_time<_Duration2, _TimeZonePtr2>& __zt)
3088 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3090 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3092 : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3095 template<typename _Duration2, typename _TimeZonePtr2>
3096 zoned_time(string_view __name,
3097 const zoned_time<_Duration2, _TimeZonePtr2>& __zt,
3099 requires is_convertible_v<sys_time<_Duration2>, sys_time<_Duration>>
3101 { _Traits::locate_zone(__name) } -> convertible_to<_TimeZonePtr>;
3103 : _M_zone(_Traits::locate_zone(__name)), _M_tp(__zt._M_tp)
3107 operator=(const sys_time<_Duration>& __st)
3114 operator=(const local_time<_Duration>& __lt)
3116 _M_tp = _M_zone->to_sys(__lt);
3121 operator sys_time<duration>() const { return _M_tp; }
3124 explicit operator local_time<duration>() const
3125 { return get_local_time(); }
3129 get_time_zone() const
3133 local_time<duration>
3134 get_local_time() const
3135 { return _M_zone->to_local(_M_tp); }
3139 get_sys_time() const
3145 { return _M_zone->get_info(_M_tp); }
3147 [[nodiscard]] friend bool
3148 operator==(const zoned_time&, const zoned_time&) = default;
3151 _TimeZonePtr _M_zone{ _Traits::default_zone() };
3152 sys_time<duration> _M_tp{};
3154 template<typename _Duration2, typename _TimeZonePtr2>
3155 friend class zoned_time;
3158 zoned_time() -> zoned_time<seconds>;
3160 template<typename _Duration>
3161 zoned_time(sys_time<_Duration>)
3162 -> zoned_time<common_type_t<_Duration, seconds>>;
3164 /// @cond undocumented
3165 template<typename _TimeZonePtrOrName>
3166 using __time_zone_representation
3167 = __conditional_t<is_convertible_v<_TimeZonePtrOrName, string_view>,
3169 remove_cvref_t<_TimeZonePtrOrName>>;
3172 template<typename _TimeZonePtrOrName>
3173 zoned_time(_TimeZonePtrOrName&&)
3174 -> zoned_time<seconds, __time_zone_representation<_TimeZonePtrOrName>>;
3176 template<typename _TimeZonePtrOrName, typename _Duration>
3177 zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>)
3178 -> zoned_time<common_type_t<_Duration, seconds>,
3179 __time_zone_representation<_TimeZonePtrOrName>>;
3181 template<typename _TimeZonePtrOrName, typename _Duration>
3182 zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>,
3183 choose = choose::earliest)
3184 -> zoned_time<common_type_t<_Duration, seconds>,
3185 __time_zone_representation<_TimeZonePtrOrName>>;
3187 template<typename _Duration, typename _TimeZonePtrOrName,
3188 typename _TimeZonePtr2>
3189 zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>,
3190 choose = choose::earliest)
3191 -> zoned_time<common_type_t<_Duration, seconds>,
3192 __time_zone_representation<_TimeZonePtrOrName>>;
3194 template<typename _Dur1, typename _TZPtr1, typename _Dur2, typename _TZPtr2>
3197 operator==(const zoned_time<_Dur1, _TZPtr1>& __x,
3198 const zoned_time<_Dur2, _TZPtr2>& __y)
3200 return __x.get_time_zone() == __y.get_time_zone()
3201 && __x.get_sys_time() == __y.get_sys_time();
3204 using zoned_seconds = zoned_time<seconds>;
3205 #endif // _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3209 inline leap_second_info
3210 __get_leap_second_info(sys_seconds __ss, bool __is_utc)
3212 if (__ss < sys_seconds{}) [[unlikely]]
3215 const seconds::rep __leaps[] {
3216 78796800, // 1 Jul 1972
3217 94694400, // 1 Jan 1973
3218 126230400, // 1 Jan 1974
3219 157766400, // 1 Jan 1975
3220 189302400, // 1 Jan 1976
3221 220924800, // 1 Jan 1977
3222 252460800, // 1 Jan 1978
3223 283996800, // 1 Jan 1979
3224 315532800, // 1 Jan 1980
3225 362793600, // 1 Jul 1981
3226 394329600, // 1 Jul 1982
3227 425865600, // 1 Jul 1983
3228 489024000, // 1 Jul 1985
3229 567993600, // 1 Jan 1988
3230 631152000, // 1 Jan 1990
3231 662688000, // 1 Jan 1991
3232 709948800, // 1 Jul 1992
3233 741484800, // 1 Jul 1993
3234 773020800, // 1 Jul 1994
3235 820454400, // 1 Jan 1996
3236 867715200, // 1 Jul 1997
3237 915148800, // 1 Jan 1999
3238 1136073600, // 1 Jan 2006
3239 1230768000, // 1 Jan 2009
3240 1341100800, // 1 Jul 2012
3241 1435708800, // 1 Jul 2015
3242 1483228800, // 1 Jan 2017
3244 // The list above is known to be valid until (at least) this date
3245 // and only contains positive leap seconds.
3246 const sys_seconds __expires(1735344000s); // 2024-12-28 00:00:00 UTC
3248 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
3249 if (__ss > __expires)
3251 // Use updated leap_seconds from tzdb.
3252 size_t __n = std::size(__leaps);
3254 auto __db = get_tzdb_list().begin();
3255 auto __first = __db->leap_seconds.begin() + __n;
3256 auto __last = __db->leap_seconds.end();
3257 auto __pos = std::upper_bound(__first, __last, __ss);
3258 seconds __elapsed(__n);
3259 for (auto __i = __first; __i != __pos; ++__i)
3260 __elapsed += __i->value();
3264 // Convert utc_time to sys_time:
3266 // See if that sys_time is before (or during) previous leap sec:
3267 if (__pos != __first && __ss < __pos[-1])
3269 if ((__ss + 1s) >= __pos[-1])
3270 return {true, __elapsed};
3271 __elapsed -= __pos[-1].value();
3274 return {false, __elapsed};
3279 seconds::rep __s = __ss.time_since_epoch().count();
3280 const seconds::rep* __first = std::begin(__leaps);
3281 const seconds::rep* __last = std::end(__leaps);
3283 // Don't bother searching the list if we're after the last one.
3284 if (__s > (__last[-1] + (__last - __first) + 1))
3285 return { false, seconds(__last - __first) };
3287 auto __pos = std::upper_bound(__first, __last, __s);
3288 seconds __elapsed{__pos - __first};
3291 // Convert utc_time to sys_time:
3292 __s -= __elapsed.count();
3293 // See if that sys_time is before (or during) previous leap sec:
3294 if (__pos != __first && __s < __pos[-1])
3296 if ((__s + 1) >= __pos[-1])
3297 return {true, __elapsed};
3301 return {false, __elapsed};
3304 } // namespace __detail
3306 template<typename _Duration>
3308 inline leap_second_info
3309 get_leap_second_info(const utc_time<_Duration>& __ut)
3311 auto __s = chrono::duration_cast<seconds>(__ut.time_since_epoch());
3312 return __detail::__get_leap_second_info(sys_seconds(__s), true);
3315 template<typename _Duration>
3317 inline utc_time<common_type_t<_Duration, seconds>>
3318 utc_clock::from_sys(const sys_time<_Duration>& __t)
3320 using _CDur = common_type_t<_Duration, seconds>;
3321 auto __s = chrono::time_point_cast<seconds>(__t);
3322 const auto __li = __detail::__get_leap_second_info(__s, false);
3323 return utc_time<_CDur>{__t.time_since_epoch()} + __li.elapsed;
3328 } // namespace chrono
3330 #if __cplusplus >= 202002L
3331 inline namespace literals
3333 inline namespace chrono_literals
3335 /// @addtogroup chrono
3337 #pragma GCC diagnostic push
3338 #pragma GCC diagnostic ignored "-Wliteral-suffix"
3339 /// Literal suffix for creating chrono::day objects.
3341 constexpr chrono::day
3342 operator""d(unsigned long long __d) noexcept
3343 { return chrono::day{static_cast<unsigned>(__d)}; }
3345 /// Literal suffix for creating chrono::year objects.
3347 constexpr chrono::year
3348 operator""y(unsigned long long __y) noexcept
3349 { return chrono::year{static_cast<int>(__y)}; }
3350 #pragma GCC diagnostic pop
3352 } // inline namespace chrono_literals
3353 } // inline namespace literals
3356 _GLIBCXX_END_NAMESPACE_VERSION
3359 #if __cplusplus >= 202002L
3360 # include <bits/chrono_io.h>
3365 #endif //_GLIBCXX_CHRONO