File indexing completed on 2026-05-03 08:13:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef _LIBCPP___CHRONO_TIME_ZONE_H
0013 #define _LIBCPP___CHRONO_TIME_ZONE_H
0014
0015 #include <version>
0016
0017 #if _LIBCPP_HAS_EXPERIMENTAL_TZDB
0018
0019 # include <__chrono/calendar.h>
0020 # include <__chrono/duration.h>
0021 # include <__chrono/exception.h>
0022 # include <__chrono/local_info.h>
0023 # include <__chrono/sys_info.h>
0024 # include <__chrono/system_clock.h>
0025 # include <__compare/strong_order.h>
0026 # include <__config>
0027 # include <__memory/unique_ptr.h>
0028 # include <__type_traits/common_type.h>
0029 # include <string_view>
0030
0031 # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0032 # pragma GCC system_header
0033 # endif
0034
0035 _LIBCPP_PUSH_MACROS
0036 # include <__undef_macros>
0037
0038 _LIBCPP_BEGIN_NAMESPACE_STD
0039
0040 # if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
0041
0042 namespace chrono {
0043
0044 enum class choose { earliest, latest };
0045
0046 class _LIBCPP_AVAILABILITY_TZDB time_zone {
0047 _LIBCPP_HIDE_FROM_ABI time_zone() = default;
0048
0049 public:
0050 class __impl;
0051
0052
0053
0054
0055
0056
0057 [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p);
0058
0059 _LIBCPP_EXPORTED_FROM_ABI ~time_zone();
0060
0061 _LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default;
0062 _LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default;
0063
0064 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); }
0065
0066 template <class _Duration>
0067 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const {
0068 return __get_info(chrono::time_point_cast<seconds>(__time));
0069 }
0070
0071 template <class _Duration>
0072 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_info get_info(const local_time<_Duration>& __time) const {
0073 return __get_info(chrono::time_point_cast<seconds>(__time));
0074 }
0075
0076
0077
0078 template <class _Duration>
0079 _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>> to_sys(const local_time<_Duration>& __time) const {
0080 local_info __info = get_info(__time);
0081 switch (__info.result) {
0082 case local_info::unique:
0083 return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
0084
0085 case local_info::nonexistent:
0086 chrono::__throw_nonexistent_local_time(__time, __info);
0087
0088 case local_info::ambiguous:
0089 chrono::__throw_ambiguous_local_time(__time, __info);
0090 }
0091
0092
0093 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0094 __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
0095 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0096 __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
0097
0098 return {};
0099 }
0100
0101 template <class _Duration>
0102 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>>
0103 to_sys(const local_time<_Duration>& __time, choose __z) const {
0104 local_info __info = get_info(__time);
0105 switch (__info.result) {
0106 case local_info::unique:
0107 return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
0108
0109 case local_info::nonexistent:
0110
0111
0112 return sys_time<common_type_t<_Duration, seconds>>{__info.first.end};
0113
0114 case local_info::ambiguous:
0115 switch (__z) {
0116 case choose::earliest:
0117 return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
0118
0119 case choose::latest:
0120 return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.second.offset};
0121
0122
0123 }
0124 }
0125
0126
0127 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0128 __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
0129 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0130 __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
0131
0132 return {};
0133 }
0134
0135 template <class _Duration>
0136 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<common_type_t<_Duration, seconds>>
0137 to_local(const sys_time<_Duration>& __time) const {
0138 using _Dp = common_type_t<_Duration, seconds>;
0139
0140 sys_info __info = get_info(__time);
0141
0142 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0143 __info.offset >= chrono::seconds{0} || __time.time_since_epoch() >= _Dp::min() - __info.offset,
0144 "cannot convert the system time; it would be before the minimum local clock value");
0145
0146 _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
0147 __info.offset <= chrono::seconds{0} || __time.time_since_epoch() <= _Dp::max() - __info.offset,
0148 "cannot convert the system time; it would be after the maximum local clock value");
0149
0150 return local_time<_Dp>{__time.time_since_epoch() + __info.offset};
0151 }
0152
0153 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
0154
0155 private:
0156 [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
0157
0158 [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const;
0159 [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info __get_info(local_seconds __time) const;
0160
0161 unique_ptr<__impl> __impl_;
0162 };
0163
0164 [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
0165 operator==(const time_zone& __x, const time_zone& __y) noexcept {
0166 return __x.name() == __y.name();
0167 }
0168
0169 [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
0170 operator<=>(const time_zone& __x, const time_zone& __y) noexcept {
0171 return __x.name() <=> __y.name();
0172 }
0173
0174 }
0175
0176 # endif
0177
0178
0179 _LIBCPP_END_NAMESPACE_STD
0180
0181 _LIBCPP_POP_MACROS
0182
0183 #endif
0184
0185 #endif