Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/include/__chrono/time_zone.h
35262 views
1
// -*- C++ -*-
2
//===----------------------------------------------------------------------===//
3
//
4
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
// See https://llvm.org/LICENSE.txt for license information.
6
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
//
8
//===----------------------------------------------------------------------===//
9
10
// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
11
12
#ifndef _LIBCPP___CHRONO_TIME_ZONE_H
13
#define _LIBCPP___CHRONO_TIME_ZONE_H
14
15
#include <version>
16
// Enable the contents of the header only when libc++ was built with experimental features enabled.
17
#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
18
19
# include <__chrono/calendar.h>
20
# include <__chrono/duration.h>
21
# include <__chrono/exception.h>
22
# include <__chrono/local_info.h>
23
# include <__chrono/sys_info.h>
24
# include <__chrono/system_clock.h>
25
# include <__compare/strong_order.h>
26
# include <__config>
27
# include <__memory/unique_ptr.h>
28
# include <__type_traits/common_type.h>
29
# include <string_view>
30
31
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32
# pragma GCC system_header
33
# endif
34
35
_LIBCPP_PUSH_MACROS
36
# include <__undef_macros>
37
38
_LIBCPP_BEGIN_NAMESPACE_STD
39
40
# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \
41
!defined(_LIBCPP_HAS_NO_LOCALIZATION)
42
43
namespace chrono {
44
45
enum class choose { earliest, latest };
46
47
class _LIBCPP_AVAILABILITY_TZDB time_zone {
48
_LIBCPP_HIDE_FROM_ABI time_zone() = default;
49
50
public:
51
class __impl; // public so it can be used by make_unique.
52
53
// The "constructor".
54
//
55
// The default constructor is private to avoid the constructor from being
56
// part of the ABI. Instead use an __ugly_named function as an ABI interface,
57
// since that gives us the ability to change it in the future.
58
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p);
59
60
_LIBCPP_EXPORTED_FROM_ABI ~time_zone();
61
62
_LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default;
63
_LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default;
64
65
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); }
66
67
template <class _Duration>
68
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const {
69
return __get_info(chrono::time_point_cast<seconds>(__time));
70
}
71
72
template <class _Duration>
73
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_info get_info(const local_time<_Duration>& __time) const {
74
return __get_info(chrono::time_point_cast<seconds>(__time));
75
}
76
77
// We don't apply nodiscard here since this function throws on many inputs,
78
// so it could be used as a validation.
79
template <class _Duration>
80
_LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>> to_sys(const local_time<_Duration>& __time) const {
81
local_info __info = get_info(__time);
82
switch (__info.result) {
83
case local_info::unique:
84
return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
85
86
case local_info::nonexistent:
87
chrono::__throw_nonexistent_local_time(__time, __info);
88
89
case local_info::ambiguous:
90
chrono::__throw_ambiguous_local_time(__time, __info);
91
}
92
93
// TODO TZDB The Standard does not specify anything in these cases.
94
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
95
__info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
96
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
97
__info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
98
99
return {};
100
}
101
102
template <class _Duration>
103
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>>
104
to_sys(const local_time<_Duration>& __time, choose __z) const {
105
local_info __info = get_info(__time);
106
switch (__info.result) {
107
case local_info::unique:
108
case local_info::nonexistent: // first and second are the same
109
return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
110
111
case local_info::ambiguous:
112
switch (__z) {
113
case choose::earliest:
114
return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
115
116
case choose::latest:
117
return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.second.offset};
118
119
// Note a value out of bounds is not specified.
120
}
121
}
122
123
// TODO TZDB The standard does not specify anything in these cases.
124
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
125
__info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
126
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
127
__info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
128
129
return {};
130
}
131
132
template <class _Duration>
133
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<common_type_t<_Duration, seconds>>
134
to_local(const sys_time<_Duration>& __time) const {
135
using _Dp = common_type_t<_Duration, seconds>;
136
137
sys_info __info = get_info(__time);
138
139
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
140
__info.offset >= chrono::seconds{0} || __time.time_since_epoch() >= _Dp::min() - __info.offset,
141
"cannot convert the system time; it would be before the minimum local clock value");
142
143
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
144
__info.offset <= chrono::seconds{0} || __time.time_since_epoch() <= _Dp::max() - __info.offset,
145
"cannot convert the system time; it would be after the maximum local clock value");
146
147
return local_time<_Dp>{__time.time_since_epoch() + __info.offset};
148
}
149
150
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
151
152
private:
153
[[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
154
155
[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const;
156
[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info __get_info(local_seconds __time) const;
157
158
unique_ptr<__impl> __impl_;
159
};
160
161
[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool
162
operator==(const time_zone& __x, const time_zone& __y) noexcept {
163
return __x.name() == __y.name();
164
}
165
166
[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering
167
operator<=>(const time_zone& __x, const time_zone& __y) noexcept {
168
return __x.name() <=> __y.name();
169
}
170
171
} // namespace chrono
172
173
# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
174
// && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
175
176
_LIBCPP_END_NAMESPACE_STD
177
178
_LIBCPP_POP_MACROS
179
180
#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
181
182
#endif // _LIBCPP___CHRONO_TIME_ZONE_H
183
184