File indexing completed on 2026-05-03 08:13:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CHRONO_UTC_CLOCK_H
0011 #define _LIBCPP___CHRONO_UTC_CLOCK_H
0012
0013 #include <version>
0014
0015 #if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0016
0017 # include <__chrono/duration.h>
0018 # include <__chrono/leap_second.h>
0019 # include <__chrono/system_clock.h>
0020 # include <__chrono/time_point.h>
0021 # include <__chrono/tzdb.h>
0022 # include <__chrono/tzdb_list.h>
0023 # include <__config>
0024 # include <__type_traits/common_type.h>
0025
0026 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0027 # pragma GCC system_header
0028 # endif
0029
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031
0032 # if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
0033
0034 namespace chrono {
0035
0036 class utc_clock;
0037
0038 template <class _Duration>
0039 using utc_time = time_point<utc_clock, _Duration>;
0040 using utc_seconds = utc_time<seconds>;
0041
0042 class utc_clock {
0043 public:
0044 using rep = system_clock::rep;
0045 using period = system_clock::period;
0046 using duration = chrono::duration<rep, period>;
0047 using time_point = chrono::time_point<utc_clock>;
0048 static constexpr bool is_steady = false;
0049
0050 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static time_point now() { return from_sys(system_clock::now()); }
0051
0052 template <class _Duration>
0053 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static sys_time<common_type_t<_Duration, seconds>>
0054 to_sys(const utc_time<_Duration>& __time);
0055
0056 template <class _Duration>
0057 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static utc_time<common_type_t<_Duration, seconds>>
0058 from_sys(const sys_time<_Duration>& __time) {
0059 using _Rp = utc_time<common_type_t<_Duration, seconds>>;
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 const tzdb& __tzdb = chrono::get_tzdb();
0095 _Rp __result{__time.time_since_epoch()};
0096 for (const auto& __leap_second : __tzdb.leap_seconds) {
0097 if (__leap_second > __time)
0098 return __result;
0099
0100 __result += __leap_second.value();
0101 }
0102 return __result;
0103 }
0104 };
0105
0106 struct leap_second_info {
0107 bool is_leap_second;
0108 seconds elapsed;
0109 };
0110
0111 template <class _Duration>
0112 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI leap_second_info get_leap_second_info(const utc_time<_Duration>& __time) {
0113 const tzdb& __tzdb = chrono::get_tzdb();
0114 if (__tzdb.leap_seconds.empty()) [[unlikely]]
0115 return {false, chrono::seconds{0}};
0116
0117 sys_seconds __sys{chrono::floor<seconds>(__time).time_since_epoch()};
0118 seconds __elapsed{0};
0119 for (const auto& __leap_second : __tzdb.leap_seconds) {
0120 if (__sys == __leap_second.date() + __elapsed)
0121
0122
0123
0124 return {__leap_second.value() > 0s, __elapsed + __leap_second.value()};
0125
0126 if (__sys < __leap_second.date() + __elapsed)
0127 return {false, __elapsed};
0128
0129 __elapsed += __leap_second.value();
0130 }
0131
0132 return {false, __elapsed};
0133 }
0134
0135 template <class _Duration>
0136 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>>
0137 utc_clock::to_sys(const utc_time<_Duration>& __time) {
0138 using _Dp = common_type_t<_Duration, seconds>;
0139 leap_second_info __info = chrono::get_leap_second_info(__time);
0140
0141
0142
0143
0144
0145
0146
0147 sys_time<common_type_t<_Duration, seconds>> __result{__time.time_since_epoch() - __info.elapsed};
0148 if (__info.is_leap_second)
0149 return chrono::floor<seconds>(__result) + chrono::seconds{1} - _Dp{1};
0150
0151 return __result;
0152 }
0153
0154 }
0155
0156 # endif
0157
0158
0159 _LIBCPP_END_NAMESPACE_STD
0160
0161 #endif
0162
0163 #endif