|
ferencd@0
|
1 #ifndef TZ_H
|
|
ferencd@0
|
2 #define TZ_H
|
|
ferencd@0
|
3
|
|
ferencd@0
|
4 // The MIT License (MIT)
|
|
ferencd@0
|
5 //
|
|
ferencd@0
|
6 // Copyright (c) 2015, 2016, 2017 Howard Hinnant
|
|
ferencd@0
|
7 // Copyright (c) 2017 Jiangang Zhuang
|
|
ferencd@0
|
8 // Copyright (c) 2017 Aaron Bishop
|
|
ferencd@0
|
9 // Copyright (c) 2017 Tomasz KamiĆski
|
|
ferencd@0
|
10 //
|
|
ferencd@0
|
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
ferencd@0
|
12 // of this software and associated documentation files (the "Software"), to deal
|
|
ferencd@0
|
13 // in the Software without restriction, including without limitation the rights
|
|
ferencd@0
|
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
ferencd@0
|
15 // copies of the Software, and to permit persons to whom the Software is
|
|
ferencd@0
|
16 // furnished to do so, subject to the following conditions:
|
|
ferencd@0
|
17 //
|
|
ferencd@0
|
18 // The above copyright notice and this permission notice shall be included in all
|
|
ferencd@0
|
19 // copies or substantial portions of the Software.
|
|
ferencd@0
|
20 //
|
|
ferencd@0
|
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
ferencd@0
|
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
ferencd@0
|
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
ferencd@0
|
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
ferencd@0
|
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
ferencd@0
|
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
ferencd@0
|
27 // SOFTWARE.
|
|
ferencd@0
|
28 //
|
|
ferencd@0
|
29 // Our apologies. When the previous paragraph was written, lowercase had not yet
|
|
ferencd@0
|
30 // been invented (that would involve another several millennia of evolution).
|
|
ferencd@0
|
31 // We did not mean to shout.
|
|
ferencd@0
|
32
|
|
ferencd@0
|
33 // Get more recent database at http://www.iana.org/time-zones
|
|
ferencd@0
|
34
|
|
ferencd@0
|
35 // The notion of "current timezone" is something the operating system is expected to "just
|
|
ferencd@0
|
36 // know". How it knows this is system specific. It's often a value set by the user at OS
|
|
ferencd@0
|
37 // installation time and recorded by the OS somewhere. On Linux and Mac systems the current
|
|
ferencd@0
|
38 // timezone name is obtained by looking at the name or contents of a particular file on
|
|
ferencd@0
|
39 // disk. On Windows the current timezone name comes from the registry. In either method,
|
|
ferencd@0
|
40 // there is no guarantee that the "native" current timezone name obtained will match any
|
|
ferencd@0
|
41 // of the "Standard" names in this library's "database". On Linux, the names usually do
|
|
ferencd@0
|
42 // seem to match so mapping functions to map from native to "Standard" are typically not
|
|
ferencd@0
|
43 // required. On Windows, the names are never "Standard" so mapping is always required.
|
|
ferencd@0
|
44 // Technically any OS may use the mapping process but currently only Windows does use it.
|
|
ferencd@0
|
45
|
|
ferencd@0
|
46 #ifndef USE_OS_TZDB
|
|
ferencd@0
|
47 # define USE_OS_TZDB 0
|
|
ferencd@0
|
48 #endif
|
|
ferencd@0
|
49
|
|
ferencd@0
|
50 #ifndef HAS_REMOTE_API
|
|
ferencd@0
|
51 # if USE_OS_TZDB == 0
|
|
ferencd@0
|
52 # ifdef _WIN32
|
|
ferencd@0
|
53 # define HAS_REMOTE_API 0
|
|
ferencd@0
|
54 # else
|
|
ferencd@0
|
55 # define HAS_REMOTE_API 1
|
|
ferencd@0
|
56 # endif
|
|
ferencd@0
|
57 # else // HAS_REMOTE_API makes no since when using the OS timezone database
|
|
ferencd@0
|
58 # define HAS_REMOTE_API 0
|
|
ferencd@0
|
59 # endif
|
|
ferencd@0
|
60 #endif
|
|
ferencd@0
|
61
|
|
ferencd@0
|
62 #ifdef __clang__
|
|
ferencd@0
|
63 # pragma clang diagnostic push
|
|
ferencd@0
|
64 # pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
|
ferencd@0
|
65 #endif
|
|
ferencd@0
|
66
|
|
ferencd@0
|
67 static_assert(!(USE_OS_TZDB && HAS_REMOTE_API),
|
|
ferencd@0
|
68 "USE_OS_TZDB and HAS_REMOTE_API can not be used together");
|
|
ferencd@0
|
69
|
|
ferencd@0
|
70 #ifdef __clang__
|
|
ferencd@0
|
71 # pragma clang diagnostic pop
|
|
ferencd@0
|
72 #endif
|
|
ferencd@0
|
73
|
|
ferencd@0
|
74 #ifndef AUTO_DOWNLOAD
|
|
ferencd@0
|
75 # define AUTO_DOWNLOAD HAS_REMOTE_API
|
|
ferencd@0
|
76 #endif
|
|
ferencd@0
|
77
|
|
ferencd@0
|
78 static_assert(HAS_REMOTE_API == 0 ? AUTO_DOWNLOAD == 0 : true,
|
|
ferencd@0
|
79 "AUTO_DOWNLOAD can not be turned on without HAS_REMOTE_API");
|
|
ferencd@0
|
80
|
|
ferencd@0
|
81 #ifndef USE_SHELL_API
|
|
ferencd@0
|
82 # define USE_SHELL_API 1
|
|
ferencd@0
|
83 #endif
|
|
ferencd@0
|
84
|
|
ferencd@0
|
85 #if USE_OS_TZDB
|
|
ferencd@0
|
86 # ifdef _WIN32
|
|
ferencd@0
|
87 # error "USE_OS_TZDB can not be used on Windows"
|
|
ferencd@0
|
88 # endif
|
|
ferencd@0
|
89 # ifndef MISSING_LEAP_SECONDS
|
|
ferencd@0
|
90 # ifdef __APPLE__
|
|
ferencd@0
|
91 # define MISSING_LEAP_SECONDS 1
|
|
ferencd@0
|
92 # else
|
|
ferencd@0
|
93 # define MISSING_LEAP_SECONDS 0
|
|
ferencd@0
|
94 # endif
|
|
ferencd@0
|
95 # endif
|
|
ferencd@0
|
96 #else
|
|
ferencd@0
|
97 # define MISSING_LEAP_SECONDS 0
|
|
ferencd@0
|
98 #endif
|
|
ferencd@0
|
99
|
|
ferencd@0
|
100 #ifndef HAS_DEDUCTION_GUIDES
|
|
ferencd@0
|
101 # if __cplusplus >= 201703
|
|
ferencd@0
|
102 # define HAS_DEDUCTION_GUIDES 1
|
|
ferencd@0
|
103 # else
|
|
ferencd@0
|
104 # define HAS_DEDUCTION_GUIDES 0
|
|
ferencd@0
|
105 # endif
|
|
ferencd@0
|
106 #endif // HAS_DEDUCTION_GUIDES
|
|
ferencd@0
|
107
|
|
ferencd@0
|
108 #include "date.h"
|
|
ferencd@0
|
109
|
|
ferencd@0
|
110 #if defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
111 #include "tz_private.h"
|
|
ferencd@0
|
112 #endif
|
|
ferencd@0
|
113
|
|
ferencd@0
|
114 #include <algorithm>
|
|
ferencd@0
|
115 #include <atomic>
|
|
ferencd@0
|
116 #include <cassert>
|
|
ferencd@0
|
117 #include <chrono>
|
|
ferencd@0
|
118 #include <istream>
|
|
ferencd@0
|
119 #include <locale>
|
|
ferencd@0
|
120 #include <memory>
|
|
ferencd@0
|
121 #include <mutex>
|
|
ferencd@0
|
122 #include <ostream>
|
|
ferencd@0
|
123 #include <sstream>
|
|
ferencd@0
|
124 #include <stdexcept>
|
|
ferencd@0
|
125 #include <string>
|
|
ferencd@0
|
126 #include <type_traits>
|
|
ferencd@0
|
127 #include <utility>
|
|
ferencd@0
|
128 #include <vector>
|
|
ferencd@0
|
129
|
|
ferencd@0
|
130 #ifdef _WIN32
|
|
ferencd@0
|
131 # ifdef DATE_BUILD_DLL
|
|
ferencd@0
|
132 # define DATE_API __declspec(dllexport)
|
|
ferencd@0
|
133 # elif defined(DATE_USE_DLL)
|
|
ferencd@0
|
134 # define DATE_API __declspec(dllimport)
|
|
ferencd@0
|
135 # else
|
|
ferencd@0
|
136 # define DATE_API
|
|
ferencd@0
|
137 # endif
|
|
ferencd@0
|
138 #else
|
|
ferencd@0
|
139 # ifdef DATE_BUILD_DLL
|
|
ferencd@0
|
140 # define DATE_API __attribute__ ((visibility ("default")))
|
|
ferencd@0
|
141 # else
|
|
ferencd@0
|
142 # define DATE_API
|
|
ferencd@0
|
143 # endif
|
|
ferencd@0
|
144 #endif
|
|
ferencd@0
|
145
|
|
ferencd@0
|
146 namespace date
|
|
ferencd@0
|
147 {
|
|
ferencd@0
|
148
|
|
ferencd@0
|
149 enum class choose {earliest, latest};
|
|
ferencd@0
|
150
|
|
ferencd@0
|
151 namespace detail
|
|
ferencd@0
|
152 {
|
|
ferencd@0
|
153 struct undocumented;
|
|
ferencd@0
|
154
|
|
ferencd@0
|
155 template<typename T>
|
|
ferencd@0
|
156 struct nodeduct
|
|
ferencd@0
|
157 {
|
|
ferencd@0
|
158 using type = T;
|
|
ferencd@0
|
159 };
|
|
ferencd@0
|
160
|
|
ferencd@0
|
161 template<typename T>
|
|
ferencd@0
|
162 using nodeduct_t = typename nodeduct<T>::type;
|
|
ferencd@0
|
163 }
|
|
ferencd@0
|
164
|
|
ferencd@0
|
165 struct sys_info
|
|
ferencd@0
|
166 {
|
|
ferencd@0
|
167 sys_seconds begin;
|
|
ferencd@0
|
168 sys_seconds end;
|
|
ferencd@0
|
169 std::chrono::seconds offset;
|
|
ferencd@0
|
170 std::chrono::minutes save;
|
|
ferencd@0
|
171 std::string abbrev;
|
|
ferencd@0
|
172 };
|
|
ferencd@0
|
173
|
|
ferencd@0
|
174 template<class CharT, class Traits>
|
|
ferencd@0
|
175 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
176 operator<<(std::basic_ostream<CharT, Traits>& os, const sys_info& r)
|
|
ferencd@0
|
177 {
|
|
ferencd@0
|
178 os << r.begin << '\n';
|
|
ferencd@0
|
179 os << r.end << '\n';
|
|
ferencd@0
|
180 os << make_time(r.offset) << "\n";
|
|
ferencd@0
|
181 os << make_time(r.save) << "\n";
|
|
ferencd@0
|
182 os << r.abbrev << '\n';
|
|
ferencd@0
|
183 return os;
|
|
ferencd@0
|
184 }
|
|
ferencd@0
|
185
|
|
ferencd@0
|
186 struct local_info
|
|
ferencd@0
|
187 {
|
|
ferencd@0
|
188 enum {unique, nonexistent, ambiguous} result;
|
|
ferencd@0
|
189 sys_info first;
|
|
ferencd@0
|
190 sys_info second;
|
|
ferencd@0
|
191 };
|
|
ferencd@0
|
192
|
|
ferencd@0
|
193 template<class CharT, class Traits>
|
|
ferencd@0
|
194 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
195 operator<<(std::basic_ostream<CharT, Traits>& os, const local_info& r)
|
|
ferencd@0
|
196 {
|
|
ferencd@0
|
197 if (r.result == local_info::nonexistent)
|
|
ferencd@0
|
198 os << "nonexistent between\n";
|
|
ferencd@0
|
199 else if (r.result == local_info::ambiguous)
|
|
ferencd@0
|
200 os << "ambiguous between\n";
|
|
ferencd@0
|
201 os << r.first;
|
|
ferencd@0
|
202 if (r.result != local_info::unique)
|
|
ferencd@0
|
203 {
|
|
ferencd@0
|
204 os << "and\n";
|
|
ferencd@0
|
205 os << r.second;
|
|
ferencd@0
|
206 }
|
|
ferencd@0
|
207 return os;
|
|
ferencd@0
|
208 }
|
|
ferencd@0
|
209
|
|
ferencd@0
|
210 class nonexistent_local_time
|
|
ferencd@0
|
211 : public std::runtime_error
|
|
ferencd@0
|
212 {
|
|
ferencd@0
|
213 public:
|
|
ferencd@0
|
214 template <class Duration>
|
|
ferencd@0
|
215 nonexistent_local_time(local_time<Duration> tp, const local_info& i);
|
|
ferencd@0
|
216
|
|
ferencd@0
|
217 private:
|
|
ferencd@0
|
218 template <class Duration>
|
|
ferencd@0
|
219 static
|
|
ferencd@0
|
220 std::string
|
|
ferencd@0
|
221 make_msg(local_time<Duration> tp, const local_info& i);
|
|
ferencd@0
|
222 };
|
|
ferencd@0
|
223
|
|
ferencd@0
|
224 template <class Duration>
|
|
ferencd@0
|
225 inline
|
|
ferencd@0
|
226 nonexistent_local_time::nonexistent_local_time(local_time<Duration> tp,
|
|
ferencd@0
|
227 const local_info& i)
|
|
ferencd@0
|
228 : std::runtime_error(make_msg(tp, i))
|
|
ferencd@0
|
229 {
|
|
ferencd@0
|
230 }
|
|
ferencd@0
|
231
|
|
ferencd@0
|
232 template <class Duration>
|
|
ferencd@0
|
233 std::string
|
|
ferencd@0
|
234 nonexistent_local_time::make_msg(local_time<Duration> tp, const local_info& i)
|
|
ferencd@0
|
235 {
|
|
ferencd@0
|
236 assert(i.result == local_info::nonexistent);
|
|
ferencd@0
|
237 std::ostringstream os;
|
|
ferencd@0
|
238 os << tp << " is in a gap between\n"
|
|
ferencd@0
|
239 << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' '
|
|
ferencd@0
|
240 << i.first.abbrev << " and\n"
|
|
ferencd@0
|
241 << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' '
|
|
ferencd@0
|
242 << i.second.abbrev
|
|
ferencd@0
|
243 << " which are both equivalent to\n"
|
|
ferencd@0
|
244 << i.first.end << " UTC";
|
|
ferencd@0
|
245 return os.str();
|
|
ferencd@0
|
246 }
|
|
ferencd@0
|
247
|
|
ferencd@0
|
248 class ambiguous_local_time
|
|
ferencd@0
|
249 : public std::runtime_error
|
|
ferencd@0
|
250 {
|
|
ferencd@0
|
251 public:
|
|
ferencd@0
|
252 template <class Duration>
|
|
ferencd@0
|
253 ambiguous_local_time(local_time<Duration> tp, const local_info& i);
|
|
ferencd@0
|
254
|
|
ferencd@0
|
255 private:
|
|
ferencd@0
|
256 template <class Duration>
|
|
ferencd@0
|
257 static
|
|
ferencd@0
|
258 std::string
|
|
ferencd@0
|
259 make_msg(local_time<Duration> tp, const local_info& i);
|
|
ferencd@0
|
260 };
|
|
ferencd@0
|
261
|
|
ferencd@0
|
262 template <class Duration>
|
|
ferencd@0
|
263 inline
|
|
ferencd@0
|
264 ambiguous_local_time::ambiguous_local_time(local_time<Duration> tp, const local_info& i)
|
|
ferencd@0
|
265 : std::runtime_error(make_msg(tp, i))
|
|
ferencd@0
|
266 {
|
|
ferencd@0
|
267 }
|
|
ferencd@0
|
268
|
|
ferencd@0
|
269 template <class Duration>
|
|
ferencd@0
|
270 std::string
|
|
ferencd@0
|
271 ambiguous_local_time::make_msg(local_time<Duration> tp, const local_info& i)
|
|
ferencd@0
|
272 {
|
|
ferencd@0
|
273 assert(i.result == local_info::ambiguous);
|
|
ferencd@0
|
274 std::ostringstream os;
|
|
ferencd@0
|
275 os << tp << " is ambiguous. It could be\n"
|
|
ferencd@0
|
276 << tp << ' ' << i.first.abbrev << " == "
|
|
ferencd@0
|
277 << tp - i.first.offset << " UTC or\n"
|
|
ferencd@0
|
278 << tp << ' ' << i.second.abbrev << " == "
|
|
ferencd@0
|
279 << tp - i.second.offset << " UTC";
|
|
ferencd@0
|
280 return os.str();
|
|
ferencd@0
|
281 }
|
|
ferencd@0
|
282
|
|
ferencd@0
|
283 class time_zone;
|
|
ferencd@0
|
284
|
|
ferencd@0
|
285 #if HAS_STRING_VIEW
|
|
ferencd@0
|
286 DATE_API const time_zone* locate_zone(std::string_view tz_name);
|
|
ferencd@0
|
287 #else
|
|
ferencd@0
|
288 DATE_API const time_zone* locate_zone(const std::string& tz_name);
|
|
ferencd@0
|
289 #endif
|
|
ferencd@0
|
290
|
|
ferencd@0
|
291 DATE_API const time_zone* current_zone();
|
|
ferencd@0
|
292
|
|
ferencd@0
|
293 template <class T>
|
|
ferencd@0
|
294 struct zoned_traits
|
|
ferencd@0
|
295 {
|
|
ferencd@0
|
296 };
|
|
ferencd@0
|
297
|
|
ferencd@0
|
298 template <>
|
|
ferencd@0
|
299 struct zoned_traits<const time_zone*>
|
|
ferencd@0
|
300 {
|
|
ferencd@0
|
301 static
|
|
ferencd@0
|
302 const time_zone*
|
|
ferencd@0
|
303 default_zone()
|
|
ferencd@0
|
304 {
|
|
ferencd@0
|
305 return date::locate_zone("Etc/UTC");
|
|
ferencd@0
|
306 }
|
|
ferencd@0
|
307
|
|
ferencd@0
|
308 #if HAS_STRING_VIEW
|
|
ferencd@0
|
309
|
|
ferencd@0
|
310 static
|
|
ferencd@0
|
311 const time_zone*
|
|
ferencd@0
|
312 locate_zone(std::string_view name)
|
|
ferencd@0
|
313 {
|
|
ferencd@0
|
314 return date::locate_zone(name);
|
|
ferencd@0
|
315 }
|
|
ferencd@0
|
316
|
|
ferencd@0
|
317 #else // !HAS_STRING_VIEW
|
|
ferencd@0
|
318
|
|
ferencd@0
|
319 static
|
|
ferencd@0
|
320 const time_zone*
|
|
ferencd@0
|
321 locate_zone(const std::string& name)
|
|
ferencd@0
|
322 {
|
|
ferencd@0
|
323 return date::locate_zone(name);
|
|
ferencd@0
|
324 }
|
|
ferencd@0
|
325
|
|
ferencd@0
|
326 static
|
|
ferencd@0
|
327 const time_zone*
|
|
ferencd@0
|
328 locate_zone(const char* name)
|
|
ferencd@0
|
329 {
|
|
ferencd@0
|
330 return date::locate_zone(name);
|
|
ferencd@0
|
331 }
|
|
ferencd@0
|
332
|
|
ferencd@0
|
333 #endif // !HAS_STRING_VIEW
|
|
ferencd@0
|
334 };
|
|
ferencd@0
|
335
|
|
ferencd@0
|
336 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
337 class zoned_time;
|
|
ferencd@0
|
338
|
|
ferencd@0
|
339 template <class Duration1, class Duration2, class TimeZonePtr>
|
|
ferencd@0
|
340 bool
|
|
ferencd@0
|
341 operator==(const zoned_time<Duration1, TimeZonePtr>& x,
|
|
ferencd@0
|
342 const zoned_time<Duration2, TimeZonePtr>& y);
|
|
ferencd@0
|
343
|
|
ferencd@0
|
344 template <class Duration, class TimeZonePtr = const time_zone*>
|
|
ferencd@0
|
345 class zoned_time
|
|
ferencd@0
|
346 {
|
|
ferencd@0
|
347 public:
|
|
ferencd@0
|
348 using duration = typename std::common_type<Duration, std::chrono::seconds>::type;
|
|
ferencd@0
|
349
|
|
ferencd@0
|
350 private:
|
|
ferencd@0
|
351 TimeZonePtr zone_;
|
|
ferencd@0
|
352 sys_time<duration> tp_;
|
|
ferencd@0
|
353
|
|
ferencd@0
|
354 public:
|
|
ferencd@0
|
355 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
356 template <class T = TimeZonePtr,
|
|
ferencd@0
|
357 class = decltype(zoned_traits<T>::default_zone())>
|
|
ferencd@0
|
358 #endif
|
|
ferencd@0
|
359 zoned_time();
|
|
ferencd@0
|
360
|
|
ferencd@0
|
361 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
362 template <class T = TimeZonePtr,
|
|
ferencd@0
|
363 class = decltype(zoned_traits<T>::default_zone())>
|
|
ferencd@0
|
364 #endif
|
|
ferencd@0
|
365 zoned_time(const sys_time<Duration>& st);
|
|
ferencd@0
|
366 explicit zoned_time(TimeZonePtr z);
|
|
ferencd@0
|
367
|
|
ferencd@0
|
368 #if HAS_STRING_VIEW
|
|
ferencd@0
|
369 template <class T = TimeZonePtr,
|
|
ferencd@0
|
370 class = typename std::enable_if
|
|
ferencd@0
|
371 <
|
|
ferencd@0
|
372 std::is_constructible
|
|
ferencd@0
|
373 <
|
|
ferencd@0
|
374 zoned_time,
|
|
ferencd@0
|
375 decltype(zoned_traits<T>::locate_zone(std::string_view()))
|
|
ferencd@0
|
376 >::value
|
|
ferencd@0
|
377 >::type>
|
|
ferencd@0
|
378 explicit zoned_time(std::string_view name);
|
|
ferencd@0
|
379 #else
|
|
ferencd@0
|
380 # if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
381 template <class T = TimeZonePtr,
|
|
ferencd@0
|
382 class = typename std::enable_if
|
|
ferencd@0
|
383 <
|
|
ferencd@0
|
384 std::is_constructible
|
|
ferencd@0
|
385 <
|
|
ferencd@0
|
386 zoned_time,
|
|
ferencd@0
|
387 decltype(zoned_traits<T>::locate_zone(std::string()))
|
|
ferencd@0
|
388 >::value
|
|
ferencd@0
|
389 >::type>
|
|
ferencd@0
|
390 # endif
|
|
ferencd@0
|
391 explicit zoned_time(const std::string& name);
|
|
ferencd@0
|
392 #endif
|
|
ferencd@0
|
393
|
|
ferencd@0
|
394 template <class Duration2,
|
|
ferencd@0
|
395 class = typename std::enable_if
|
|
ferencd@0
|
396 <
|
|
ferencd@0
|
397 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
398 sys_time<Duration>>::value
|
|
ferencd@0
|
399 >::type>
|
|
ferencd@0
|
400 zoned_time(const zoned_time<Duration2, TimeZonePtr>& zt) NOEXCEPT;
|
|
ferencd@0
|
401
|
|
ferencd@0
|
402 zoned_time(TimeZonePtr z, const sys_time<Duration>& st);
|
|
ferencd@0
|
403
|
|
ferencd@0
|
404 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
405 template <class T = TimeZonePtr,
|
|
ferencd@0
|
406 class = typename std::enable_if
|
|
ferencd@0
|
407 <
|
|
ferencd@0
|
408 std::is_convertible
|
|
ferencd@0
|
409 <
|
|
ferencd@0
|
410 decltype(std::declval<T&>()->to_sys(local_time<Duration>{})),
|
|
ferencd@0
|
411 sys_time<duration>
|
|
ferencd@0
|
412 >::value
|
|
ferencd@0
|
413 >::type>
|
|
ferencd@0
|
414 #endif
|
|
ferencd@0
|
415 zoned_time(TimeZonePtr z, const local_time<Duration>& tp);
|
|
ferencd@0
|
416
|
|
ferencd@0
|
417 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
418 template <class T = TimeZonePtr,
|
|
ferencd@0
|
419 class = typename std::enable_if
|
|
ferencd@0
|
420 <
|
|
ferencd@0
|
421 std::is_convertible
|
|
ferencd@0
|
422 <
|
|
ferencd@0
|
423 decltype(std::declval<T&>()->to_sys(local_time<Duration>{},
|
|
ferencd@0
|
424 choose::earliest)),
|
|
ferencd@0
|
425 sys_time<duration>
|
|
ferencd@0
|
426 >::value
|
|
ferencd@0
|
427 >::type>
|
|
ferencd@0
|
428 #endif
|
|
ferencd@0
|
429 zoned_time(TimeZonePtr z, const local_time<Duration>& tp, choose c);
|
|
ferencd@0
|
430
|
|
ferencd@0
|
431 template <class Duration2, class TimeZonePtr2,
|
|
ferencd@0
|
432 class = typename std::enable_if
|
|
ferencd@0
|
433 <
|
|
ferencd@0
|
434 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
435 sys_time<Duration>>::value
|
|
ferencd@0
|
436 >::type>
|
|
ferencd@0
|
437 zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& zt);
|
|
ferencd@0
|
438
|
|
ferencd@0
|
439 template <class Duration2, class TimeZonePtr2,
|
|
ferencd@0
|
440 class = typename std::enable_if
|
|
ferencd@0
|
441 <
|
|
ferencd@0
|
442 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
443 sys_time<Duration>>::value
|
|
ferencd@0
|
444 >::type>
|
|
ferencd@0
|
445 zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& zt, choose);
|
|
ferencd@0
|
446
|
|
ferencd@0
|
447 #if HAS_STRING_VIEW
|
|
ferencd@0
|
448
|
|
ferencd@0
|
449 template <class T = TimeZonePtr,
|
|
ferencd@0
|
450 class = typename std::enable_if
|
|
ferencd@0
|
451 <
|
|
ferencd@0
|
452 std::is_constructible
|
|
ferencd@0
|
453 <
|
|
ferencd@0
|
454 zoned_time,
|
|
ferencd@0
|
455 decltype(zoned_traits<T>::locate_zone(std::string_view())),
|
|
ferencd@0
|
456 sys_time<Duration>
|
|
ferencd@0
|
457 >::value
|
|
ferencd@0
|
458 >::type>
|
|
ferencd@0
|
459 zoned_time(std::string_view name, detail::nodeduct_t<const sys_time<Duration>&> st);
|
|
ferencd@0
|
460
|
|
ferencd@0
|
461 template <class T = TimeZonePtr,
|
|
ferencd@0
|
462 class = typename std::enable_if
|
|
ferencd@0
|
463 <
|
|
ferencd@0
|
464 std::is_constructible
|
|
ferencd@0
|
465 <
|
|
ferencd@0
|
466 zoned_time,
|
|
ferencd@0
|
467 decltype(zoned_traits<T>::locate_zone(std::string_view())),
|
|
ferencd@0
|
468 local_time<Duration>
|
|
ferencd@0
|
469 >::value
|
|
ferencd@0
|
470 >::type>
|
|
ferencd@0
|
471 zoned_time(std::string_view name, detail::nodeduct_t<const local_time<Duration>&> tp);
|
|
ferencd@0
|
472
|
|
ferencd@0
|
473 template <class T = TimeZonePtr,
|
|
ferencd@0
|
474 class = typename std::enable_if
|
|
ferencd@0
|
475 <
|
|
ferencd@0
|
476 std::is_constructible
|
|
ferencd@0
|
477 <
|
|
ferencd@0
|
478 zoned_time,
|
|
ferencd@0
|
479 decltype(zoned_traits<T>::locate_zone(std::string_view())),
|
|
ferencd@0
|
480 local_time<Duration>,
|
|
ferencd@0
|
481 choose
|
|
ferencd@0
|
482 >::value
|
|
ferencd@0
|
483 >::type>
|
|
ferencd@0
|
484 zoned_time(std::string_view name, detail::nodeduct_t<const local_time<Duration>&> tp, choose c);
|
|
ferencd@0
|
485
|
|
ferencd@0
|
486 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
487 class = typename std::enable_if
|
|
ferencd@0
|
488 <
|
|
ferencd@0
|
489 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
490 sys_time<Duration>>::value &&
|
|
ferencd@0
|
491 std::is_constructible
|
|
ferencd@0
|
492 <
|
|
ferencd@0
|
493 zoned_time,
|
|
ferencd@0
|
494 decltype(zoned_traits<T>::locate_zone(std::string_view())),
|
|
ferencd@0
|
495 zoned_time
|
|
ferencd@0
|
496 >::value
|
|
ferencd@0
|
497 >::type>
|
|
ferencd@0
|
498 zoned_time(std::string_view name, const zoned_time<Duration2, TimeZonePtr2>& zt);
|
|
ferencd@0
|
499
|
|
ferencd@0
|
500 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
501 class = typename std::enable_if
|
|
ferencd@0
|
502 <
|
|
ferencd@0
|
503 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
504 sys_time<Duration>>::value &&
|
|
ferencd@0
|
505 std::is_constructible
|
|
ferencd@0
|
506 <
|
|
ferencd@0
|
507 zoned_time,
|
|
ferencd@0
|
508 decltype(zoned_traits<T>::locate_zone(std::string_view())),
|
|
ferencd@0
|
509 zoned_time,
|
|
ferencd@0
|
510 choose
|
|
ferencd@0
|
511 >::value
|
|
ferencd@0
|
512 >::type>
|
|
ferencd@0
|
513 zoned_time(std::string_view name, const zoned_time<Duration2, TimeZonePtr2>& zt, choose);
|
|
ferencd@0
|
514
|
|
ferencd@0
|
515 #else // !HAS_STRING_VIEW
|
|
ferencd@0
|
516
|
|
ferencd@0
|
517 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
518 template <class T = TimeZonePtr,
|
|
ferencd@0
|
519 class = typename std::enable_if
|
|
ferencd@0
|
520 <
|
|
ferencd@0
|
521 std::is_constructible
|
|
ferencd@0
|
522 <
|
|
ferencd@0
|
523 zoned_time,
|
|
ferencd@0
|
524 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
525 sys_time<Duration>
|
|
ferencd@0
|
526 >::value
|
|
ferencd@0
|
527 >::type>
|
|
ferencd@0
|
528 #endif
|
|
ferencd@0
|
529 zoned_time(const std::string& name, const sys_time<Duration>& st);
|
|
ferencd@0
|
530
|
|
ferencd@0
|
531 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
532 template <class T = TimeZonePtr,
|
|
ferencd@0
|
533 class = typename std::enable_if
|
|
ferencd@0
|
534 <
|
|
ferencd@0
|
535 std::is_constructible
|
|
ferencd@0
|
536 <
|
|
ferencd@0
|
537 zoned_time,
|
|
ferencd@0
|
538 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
539 sys_time<Duration>
|
|
ferencd@0
|
540 >::value
|
|
ferencd@0
|
541 >::type>
|
|
ferencd@0
|
542 #endif
|
|
ferencd@0
|
543 zoned_time(const char* name, const sys_time<Duration>& st);
|
|
ferencd@0
|
544
|
|
ferencd@0
|
545 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
546 template <class T = TimeZonePtr,
|
|
ferencd@0
|
547 class = typename std::enable_if
|
|
ferencd@0
|
548 <
|
|
ferencd@0
|
549 std::is_constructible
|
|
ferencd@0
|
550 <
|
|
ferencd@0
|
551 zoned_time,
|
|
ferencd@0
|
552 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
553 local_time<Duration>
|
|
ferencd@0
|
554 >::value
|
|
ferencd@0
|
555 >::type>
|
|
ferencd@0
|
556 #endif
|
|
ferencd@0
|
557 zoned_time(const std::string& name, const local_time<Duration>& tp);
|
|
ferencd@0
|
558
|
|
ferencd@0
|
559 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
560 template <class T = TimeZonePtr,
|
|
ferencd@0
|
561 class = typename std::enable_if
|
|
ferencd@0
|
562 <
|
|
ferencd@0
|
563 std::is_constructible
|
|
ferencd@0
|
564 <
|
|
ferencd@0
|
565 zoned_time,
|
|
ferencd@0
|
566 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
567 local_time<Duration>
|
|
ferencd@0
|
568 >::value
|
|
ferencd@0
|
569 >::type>
|
|
ferencd@0
|
570 #endif
|
|
ferencd@0
|
571 zoned_time(const char* name, const local_time<Duration>& tp);
|
|
ferencd@0
|
572
|
|
ferencd@0
|
573 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
574 template <class T = TimeZonePtr,
|
|
ferencd@0
|
575 class = typename std::enable_if
|
|
ferencd@0
|
576 <
|
|
ferencd@0
|
577 std::is_constructible
|
|
ferencd@0
|
578 <
|
|
ferencd@0
|
579 zoned_time,
|
|
ferencd@0
|
580 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
581 local_time<Duration>,
|
|
ferencd@0
|
582 choose
|
|
ferencd@0
|
583 >::value
|
|
ferencd@0
|
584 >::type>
|
|
ferencd@0
|
585 #endif
|
|
ferencd@0
|
586 zoned_time(const std::string& name, const local_time<Duration>& tp, choose c);
|
|
ferencd@0
|
587
|
|
ferencd@0
|
588 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
589 template <class T = TimeZonePtr,
|
|
ferencd@0
|
590 class = typename std::enable_if
|
|
ferencd@0
|
591 <
|
|
ferencd@0
|
592 std::is_constructible
|
|
ferencd@0
|
593 <
|
|
ferencd@0
|
594 zoned_time,
|
|
ferencd@0
|
595 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
596 local_time<Duration>,
|
|
ferencd@0
|
597 choose
|
|
ferencd@0
|
598 >::value
|
|
ferencd@0
|
599 >::type>
|
|
ferencd@0
|
600 #endif
|
|
ferencd@0
|
601 zoned_time(const char* name, const local_time<Duration>& tp, choose c);
|
|
ferencd@0
|
602
|
|
ferencd@0
|
603 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
604 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
605 class = typename std::enable_if
|
|
ferencd@0
|
606 <
|
|
ferencd@0
|
607 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
608 sys_time<Duration>>::value &&
|
|
ferencd@0
|
609 std::is_constructible
|
|
ferencd@0
|
610 <
|
|
ferencd@0
|
611 zoned_time,
|
|
ferencd@0
|
612 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
613 zoned_time
|
|
ferencd@0
|
614 >::value
|
|
ferencd@0
|
615 >::type>
|
|
ferencd@0
|
616 #else
|
|
ferencd@0
|
617 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
618 #endif
|
|
ferencd@0
|
619 zoned_time(const std::string& name, const zoned_time<Duration2, TimeZonePtr2>& zt);
|
|
ferencd@0
|
620
|
|
ferencd@0
|
621 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
622 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
623 class = typename std::enable_if
|
|
ferencd@0
|
624 <
|
|
ferencd@0
|
625 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
626 sys_time<Duration>>::value &&
|
|
ferencd@0
|
627 std::is_constructible
|
|
ferencd@0
|
628 <
|
|
ferencd@0
|
629 zoned_time,
|
|
ferencd@0
|
630 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
631 zoned_time
|
|
ferencd@0
|
632 >::value
|
|
ferencd@0
|
633 >::type>
|
|
ferencd@0
|
634 #else
|
|
ferencd@0
|
635 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
636 #endif
|
|
ferencd@0
|
637 zoned_time(const char* name, const zoned_time<Duration2, TimeZonePtr2>& zt);
|
|
ferencd@0
|
638
|
|
ferencd@0
|
639 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
640 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
641 class = typename std::enable_if
|
|
ferencd@0
|
642 <
|
|
ferencd@0
|
643 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
644 sys_time<Duration>>::value &&
|
|
ferencd@0
|
645 std::is_constructible
|
|
ferencd@0
|
646 <
|
|
ferencd@0
|
647 zoned_time,
|
|
ferencd@0
|
648 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
649 zoned_time,
|
|
ferencd@0
|
650 choose
|
|
ferencd@0
|
651 >::value
|
|
ferencd@0
|
652 >::type>
|
|
ferencd@0
|
653 #else
|
|
ferencd@0
|
654 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
655 #endif
|
|
ferencd@0
|
656 zoned_time(const std::string& name, const zoned_time<Duration2, TimeZonePtr2>& zt,
|
|
ferencd@0
|
657 choose);
|
|
ferencd@0
|
658
|
|
ferencd@0
|
659 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
660 template <class Duration2, class TimeZonePtr2, class T = TimeZonePtr,
|
|
ferencd@0
|
661 class = typename std::enable_if
|
|
ferencd@0
|
662 <
|
|
ferencd@0
|
663 std::is_convertible<sys_time<Duration2>,
|
|
ferencd@0
|
664 sys_time<Duration>>::value &&
|
|
ferencd@0
|
665 std::is_constructible
|
|
ferencd@0
|
666 <
|
|
ferencd@0
|
667 zoned_time,
|
|
ferencd@0
|
668 decltype(zoned_traits<T>::locate_zone(std::string())),
|
|
ferencd@0
|
669 zoned_time,
|
|
ferencd@0
|
670 choose
|
|
ferencd@0
|
671 >::value
|
|
ferencd@0
|
672 >::type>
|
|
ferencd@0
|
673 #else
|
|
ferencd@0
|
674 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
675 #endif
|
|
ferencd@0
|
676 zoned_time(const char* name, const zoned_time<Duration2, TimeZonePtr2>& zt,
|
|
ferencd@0
|
677 choose);
|
|
ferencd@0
|
678
|
|
ferencd@0
|
679 #endif // !HAS_STRING_VIEW
|
|
ferencd@0
|
680
|
|
ferencd@0
|
681 zoned_time& operator=(const sys_time<Duration>& st);
|
|
ferencd@0
|
682 zoned_time& operator=(const local_time<Duration>& ut);
|
|
ferencd@0
|
683
|
|
ferencd@0
|
684 explicit operator sys_time<duration>() const;
|
|
ferencd@0
|
685 explicit operator local_time<duration>() const;
|
|
ferencd@0
|
686
|
|
ferencd@0
|
687 TimeZonePtr get_time_zone() const;
|
|
ferencd@0
|
688 local_time<duration> get_local_time() const;
|
|
ferencd@0
|
689 sys_time<duration> get_sys_time() const;
|
|
ferencd@0
|
690 sys_info get_info() const;
|
|
ferencd@0
|
691
|
|
ferencd@0
|
692 template <class Duration1, class Duration2, class TimeZonePtr1>
|
|
ferencd@0
|
693 friend
|
|
ferencd@0
|
694 bool
|
|
ferencd@0
|
695 operator==(const zoned_time<Duration1, TimeZonePtr1>& x,
|
|
ferencd@0
|
696 const zoned_time<Duration2, TimeZonePtr1>& y);
|
|
ferencd@0
|
697
|
|
ferencd@0
|
698 template <class CharT, class Traits, class Duration1, class TimeZonePtr1>
|
|
ferencd@0
|
699 friend
|
|
ferencd@0
|
700 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
701 operator<<(std::basic_ostream<CharT, Traits>& os,
|
|
ferencd@0
|
702 const zoned_time<Duration1, TimeZonePtr1>& t);
|
|
ferencd@0
|
703
|
|
ferencd@0
|
704 private:
|
|
ferencd@0
|
705 template <class D, class T> friend class zoned_time;
|
|
ferencd@0
|
706 };
|
|
ferencd@0
|
707
|
|
ferencd@0
|
708 using zoned_seconds = zoned_time<std::chrono::seconds>;
|
|
ferencd@0
|
709
|
|
ferencd@0
|
710 #if HAS_DEDUCTION_GUIDES
|
|
ferencd@0
|
711
|
|
ferencd@0
|
712 namespace detail
|
|
ferencd@0
|
713 {
|
|
ferencd@0
|
714 template<typename TimeZonePtrOrName>
|
|
ferencd@0
|
715 using time_zone_representation =
|
|
ferencd@0
|
716 std::conditional_t
|
|
ferencd@0
|
717 <
|
|
ferencd@0
|
718 std::is_convertible<TimeZonePtrOrName, std::string_view>::value,
|
|
ferencd@0
|
719 time_zone const*,
|
|
ferencd@0
|
720 std::remove_cv_t<std::remove_reference_t<TimeZonePtrOrName>>
|
|
ferencd@0
|
721 >;
|
|
ferencd@0
|
722 }
|
|
ferencd@0
|
723
|
|
ferencd@0
|
724 zoned_time()
|
|
ferencd@0
|
725 -> zoned_time<std::chrono::seconds>;
|
|
ferencd@0
|
726
|
|
ferencd@0
|
727 template <class Duration>
|
|
ferencd@0
|
728 zoned_time(sys_time<Duration>)
|
|
ferencd@0
|
729 -> zoned_time<std::common_type_t<Duration, std::chrono::seconds>>;
|
|
ferencd@0
|
730
|
|
ferencd@0
|
731 template <class TimeZonePtrOrName>
|
|
ferencd@0
|
732 zoned_time(TimeZonePtrOrName&&)
|
|
ferencd@0
|
733 -> zoned_time<std::chrono::seconds, detail::time_zone_representation<TimeZonePtrOrName>>;
|
|
ferencd@0
|
734
|
|
ferencd@0
|
735 template <class TimeZonePtrOrName, class Duration>
|
|
ferencd@0
|
736 zoned_time(TimeZonePtrOrName&&, sys_time<Duration>)
|
|
ferencd@0
|
737 -> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
|
|
ferencd@0
|
738
|
|
ferencd@0
|
739 template <class TimeZonePtrOrName, class Duration>
|
|
ferencd@0
|
740 zoned_time(TimeZonePtrOrName&&, local_time<Duration>, choose = choose::earliest)
|
|
ferencd@0
|
741 -> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
|
|
ferencd@0
|
742
|
|
ferencd@0
|
743 template <class Duration, class TimeZonePtrOrName, class TimeZonePtr2>
|
|
ferencd@0
|
744 zoned_time(TimeZonePtrOrName&&, zoned_time<Duration, TimeZonePtr2>, choose = choose::earliest)
|
|
ferencd@0
|
745 -> zoned_time<std::common_type_t<Duration, std::chrono::seconds>, detail::time_zone_representation<TimeZonePtrOrName>>;
|
|
ferencd@0
|
746
|
|
ferencd@0
|
747 #endif // HAS_DEDUCTION_GUIDES
|
|
ferencd@0
|
748
|
|
ferencd@0
|
749 template <class Duration1, class Duration2, class TimeZonePtr>
|
|
ferencd@0
|
750 inline
|
|
ferencd@0
|
751 bool
|
|
ferencd@0
|
752 operator==(const zoned_time<Duration1, TimeZonePtr>& x,
|
|
ferencd@0
|
753 const zoned_time<Duration2, TimeZonePtr>& y)
|
|
ferencd@0
|
754 {
|
|
ferencd@0
|
755 return x.zone_ == y.zone_ && x.tp_ == y.tp_;
|
|
ferencd@0
|
756 }
|
|
ferencd@0
|
757
|
|
ferencd@0
|
758 template <class Duration1, class Duration2, class TimeZonePtr>
|
|
ferencd@0
|
759 inline
|
|
ferencd@0
|
760 bool
|
|
ferencd@0
|
761 operator!=(const zoned_time<Duration1, TimeZonePtr>& x,
|
|
ferencd@0
|
762 const zoned_time<Duration2, TimeZonePtr>& y)
|
|
ferencd@0
|
763 {
|
|
ferencd@0
|
764 return !(x == y);
|
|
ferencd@0
|
765 }
|
|
ferencd@0
|
766
|
|
ferencd@0
|
767 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
|
ferencd@0
|
768
|
|
ferencd@0
|
769 namespace detail
|
|
ferencd@0
|
770 {
|
|
ferencd@0
|
771 # if USE_OS_TZDB
|
|
ferencd@0
|
772 struct transition;
|
|
ferencd@0
|
773 struct expanded_ttinfo;
|
|
ferencd@0
|
774 # else // !USE_OS_TZDB
|
|
ferencd@0
|
775 struct zonelet;
|
|
ferencd@0
|
776 class Rule;
|
|
ferencd@0
|
777 # endif // !USE_OS_TZDB
|
|
ferencd@0
|
778 }
|
|
ferencd@0
|
779
|
|
ferencd@0
|
780 #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
|
ferencd@0
|
781
|
|
ferencd@0
|
782 class time_zone
|
|
ferencd@0
|
783 {
|
|
ferencd@0
|
784 private:
|
|
ferencd@0
|
785 std::string name_;
|
|
ferencd@0
|
786 #if USE_OS_TZDB
|
|
ferencd@0
|
787 std::vector<detail::transition> transitions_;
|
|
ferencd@0
|
788 std::vector<detail::expanded_ttinfo> ttinfos_;
|
|
ferencd@0
|
789 #else // !USE_OS_TZDB
|
|
ferencd@0
|
790 std::vector<detail::zonelet> zonelets_;
|
|
ferencd@0
|
791 #endif // !USE_OS_TZDB
|
|
ferencd@0
|
792 std::unique_ptr<std::once_flag> adjusted_;
|
|
ferencd@0
|
793
|
|
ferencd@0
|
794 public:
|
|
ferencd@0
|
795 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
|
ferencd@0
|
796 time_zone(time_zone&&) = default;
|
|
ferencd@0
|
797 time_zone& operator=(time_zone&&) = default;
|
|
ferencd@0
|
798 #else // defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
799 time_zone(time_zone&& src);
|
|
ferencd@0
|
800 time_zone& operator=(time_zone&& src);
|
|
ferencd@0
|
801 #endif // defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
802
|
|
ferencd@0
|
803 DATE_API explicit time_zone(const std::string& s, detail::undocumented);
|
|
ferencd@0
|
804
|
|
ferencd@0
|
805 const std::string& name() const NOEXCEPT;
|
|
ferencd@0
|
806
|
|
ferencd@0
|
807 template <class Duration> sys_info get_info(sys_time<Duration> st) const;
|
|
ferencd@0
|
808 template <class Duration> local_info get_info(local_time<Duration> tp) const;
|
|
ferencd@0
|
809
|
|
ferencd@0
|
810 template <class Duration>
|
|
ferencd@0
|
811 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
812 to_sys(local_time<Duration> tp) const;
|
|
ferencd@0
|
813
|
|
ferencd@0
|
814 template <class Duration>
|
|
ferencd@0
|
815 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
816 to_sys(local_time<Duration> tp, choose z) const;
|
|
ferencd@0
|
817
|
|
ferencd@0
|
818 template <class Duration>
|
|
ferencd@0
|
819 local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
820 to_local(sys_time<Duration> tp) const;
|
|
ferencd@0
|
821
|
|
ferencd@0
|
822 friend bool operator==(const time_zone& x, const time_zone& y) NOEXCEPT;
|
|
ferencd@0
|
823 friend bool operator< (const time_zone& x, const time_zone& y) NOEXCEPT;
|
|
ferencd@0
|
824 friend DATE_API std::ostream& operator<<(std::ostream& os, const time_zone& z);
|
|
ferencd@0
|
825
|
|
ferencd@0
|
826 #if !USE_OS_TZDB
|
|
ferencd@0
|
827 DATE_API void add(const std::string& s);
|
|
ferencd@0
|
828 #endif // !USE_OS_TZDB
|
|
ferencd@0
|
829
|
|
ferencd@0
|
830 private:
|
|
ferencd@0
|
831 DATE_API sys_info get_info_impl(sys_seconds tp) const;
|
|
ferencd@0
|
832 DATE_API local_info get_info_impl(local_seconds tp) const;
|
|
ferencd@0
|
833
|
|
ferencd@0
|
834 template <class Duration>
|
|
ferencd@0
|
835 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
836 to_sys_impl(local_time<Duration> tp, choose z, std::false_type) const;
|
|
ferencd@0
|
837 template <class Duration>
|
|
ferencd@0
|
838 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
839 to_sys_impl(local_time<Duration> tp, choose, std::true_type) const;
|
|
ferencd@0
|
840
|
|
ferencd@0
|
841 #if USE_OS_TZDB
|
|
ferencd@0
|
842 DATE_API void init() const;
|
|
ferencd@0
|
843 DATE_API void init_impl();
|
|
ferencd@0
|
844 DATE_API sys_info
|
|
ferencd@0
|
845 load_sys_info(std::vector<detail::transition>::const_iterator i) const;
|
|
ferencd@0
|
846
|
|
ferencd@0
|
847 template <class TimeType>
|
|
ferencd@0
|
848 DATE_API void
|
|
ferencd@0
|
849 load_data(std::istream& inf, std::int32_t tzh_leapcnt, std::int32_t tzh_timecnt,
|
|
ferencd@0
|
850 std::int32_t tzh_typecnt, std::int32_t tzh_charcnt);
|
|
ferencd@0
|
851 #else // !USE_OS_TZDB
|
|
ferencd@0
|
852 DATE_API sys_info get_info_impl(sys_seconds tp, int timezone) const;
|
|
ferencd@0
|
853 DATE_API void adjust_infos(const std::vector<detail::Rule>& rules);
|
|
ferencd@0
|
854 DATE_API void parse_info(std::istream& in);
|
|
ferencd@0
|
855 #endif // !USE_OS_TZDB
|
|
ferencd@0
|
856 };
|
|
ferencd@0
|
857
|
|
ferencd@0
|
858 #if defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
859
|
|
ferencd@0
|
860 inline
|
|
ferencd@0
|
861 time_zone::time_zone(time_zone&& src)
|
|
ferencd@0
|
862 : name_(std::move(src.name_))
|
|
ferencd@0
|
863 , zonelets_(std::move(src.zonelets_))
|
|
ferencd@0
|
864 , adjusted_(std::move(src.adjusted_))
|
|
ferencd@0
|
865 {}
|
|
ferencd@0
|
866
|
|
ferencd@0
|
867 inline
|
|
ferencd@0
|
868 time_zone&
|
|
ferencd@0
|
869 time_zone::operator=(time_zone&& src)
|
|
ferencd@0
|
870 {
|
|
ferencd@0
|
871 name_ = std::move(src.name_);
|
|
ferencd@0
|
872 zonelets_ = std::move(src.zonelets_);
|
|
ferencd@0
|
873 adjusted_ = std::move(src.adjusted_);
|
|
ferencd@0
|
874 return *this;
|
|
ferencd@0
|
875 }
|
|
ferencd@0
|
876
|
|
ferencd@0
|
877 #endif // defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
878
|
|
ferencd@0
|
879 inline
|
|
ferencd@0
|
880 const std::string&
|
|
ferencd@0
|
881 time_zone::name() const NOEXCEPT
|
|
ferencd@0
|
882 {
|
|
ferencd@0
|
883 return name_;
|
|
ferencd@0
|
884 }
|
|
ferencd@0
|
885
|
|
ferencd@0
|
886 template <class Duration>
|
|
ferencd@0
|
887 inline
|
|
ferencd@0
|
888 sys_info
|
|
ferencd@0
|
889 time_zone::get_info(sys_time<Duration> st) const
|
|
ferencd@0
|
890 {
|
|
ferencd@0
|
891 return get_info_impl(date::floor<std::chrono::seconds>(st));
|
|
ferencd@0
|
892 }
|
|
ferencd@0
|
893
|
|
ferencd@0
|
894 template <class Duration>
|
|
ferencd@0
|
895 inline
|
|
ferencd@0
|
896 local_info
|
|
ferencd@0
|
897 time_zone::get_info(local_time<Duration> tp) const
|
|
ferencd@0
|
898 {
|
|
ferencd@0
|
899 return get_info_impl(date::floor<std::chrono::seconds>(tp));
|
|
ferencd@0
|
900 }
|
|
ferencd@0
|
901
|
|
ferencd@0
|
902 template <class Duration>
|
|
ferencd@0
|
903 inline
|
|
ferencd@0
|
904 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
905 time_zone::to_sys(local_time<Duration> tp) const
|
|
ferencd@0
|
906 {
|
|
ferencd@0
|
907 return to_sys_impl(tp, choose{}, std::true_type{});
|
|
ferencd@0
|
908 }
|
|
ferencd@0
|
909
|
|
ferencd@0
|
910 template <class Duration>
|
|
ferencd@0
|
911 inline
|
|
ferencd@0
|
912 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
913 time_zone::to_sys(local_time<Duration> tp, choose z) const
|
|
ferencd@0
|
914 {
|
|
ferencd@0
|
915 return to_sys_impl(tp, z, std::false_type{});
|
|
ferencd@0
|
916 }
|
|
ferencd@0
|
917
|
|
ferencd@0
|
918 template <class Duration>
|
|
ferencd@0
|
919 inline
|
|
ferencd@0
|
920 local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
921 time_zone::to_local(sys_time<Duration> tp) const
|
|
ferencd@0
|
922 {
|
|
ferencd@0
|
923 using LT = local_time<typename std::common_type<Duration, std::chrono::seconds>::type>;
|
|
ferencd@0
|
924 auto i = get_info(tp);
|
|
ferencd@0
|
925 return LT{(tp + i.offset).time_since_epoch()};
|
|
ferencd@0
|
926 }
|
|
ferencd@0
|
927
|
|
ferencd@0
|
928 inline bool operator==(const time_zone& x, const time_zone& y) NOEXCEPT {return x.name_ == y.name_;}
|
|
ferencd@0
|
929 inline bool operator< (const time_zone& x, const time_zone& y) NOEXCEPT {return x.name_ < y.name_;}
|
|
ferencd@0
|
930
|
|
ferencd@0
|
931 inline bool operator!=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(x == y);}
|
|
ferencd@0
|
932 inline bool operator> (const time_zone& x, const time_zone& y) NOEXCEPT {return y < x;}
|
|
ferencd@0
|
933 inline bool operator<=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(y < x);}
|
|
ferencd@0
|
934 inline bool operator>=(const time_zone& x, const time_zone& y) NOEXCEPT {return !(x < y);}
|
|
ferencd@0
|
935
|
|
ferencd@0
|
936 template <class Duration>
|
|
ferencd@0
|
937 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
938 time_zone::to_sys_impl(local_time<Duration> tp, choose z, std::false_type) const
|
|
ferencd@0
|
939 {
|
|
ferencd@0
|
940 auto i = get_info(tp);
|
|
ferencd@0
|
941 if (i.result == local_info::nonexistent)
|
|
ferencd@0
|
942 {
|
|
ferencd@0
|
943 return i.first.end;
|
|
ferencd@0
|
944 }
|
|
ferencd@0
|
945 else if (i.result == local_info::ambiguous)
|
|
ferencd@0
|
946 {
|
|
ferencd@0
|
947 if (z == choose::latest)
|
|
ferencd@0
|
948 return sys_time<Duration>{tp.time_since_epoch()} - i.second.offset;
|
|
ferencd@0
|
949 }
|
|
ferencd@0
|
950 return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
|
|
ferencd@0
|
951 }
|
|
ferencd@0
|
952
|
|
ferencd@0
|
953 template <class Duration>
|
|
ferencd@0
|
954 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
955 time_zone::to_sys_impl(local_time<Duration> tp, choose, std::true_type) const
|
|
ferencd@0
|
956 {
|
|
ferencd@0
|
957 auto i = get_info(tp);
|
|
ferencd@0
|
958 if (i.result == local_info::nonexistent)
|
|
ferencd@0
|
959 throw nonexistent_local_time(tp, i);
|
|
ferencd@0
|
960 else if (i.result == local_info::ambiguous)
|
|
ferencd@0
|
961 throw ambiguous_local_time(tp, i);
|
|
ferencd@0
|
962 return sys_time<Duration>{tp.time_since_epoch()} - i.first.offset;
|
|
ferencd@0
|
963 }
|
|
ferencd@0
|
964
|
|
ferencd@0
|
965 #if !USE_OS_TZDB
|
|
ferencd@0
|
966
|
|
ferencd@0
|
967 class link
|
|
ferencd@0
|
968 {
|
|
ferencd@0
|
969 private:
|
|
ferencd@0
|
970 std::string name_;
|
|
ferencd@0
|
971 std::string target_;
|
|
ferencd@0
|
972 public:
|
|
ferencd@0
|
973 DATE_API explicit link(const std::string& s);
|
|
ferencd@0
|
974
|
|
ferencd@0
|
975 const std::string& name() const {return name_;}
|
|
ferencd@0
|
976 const std::string& target() const {return target_;}
|
|
ferencd@0
|
977
|
|
ferencd@0
|
978 friend bool operator==(const link& x, const link& y) {return x.name_ == y.name_;}
|
|
ferencd@0
|
979 friend bool operator< (const link& x, const link& y) {return x.name_ < y.name_;}
|
|
ferencd@0
|
980
|
|
ferencd@0
|
981 friend DATE_API std::ostream& operator<<(std::ostream& os, const link& x);
|
|
ferencd@0
|
982 };
|
|
ferencd@0
|
983
|
|
ferencd@0
|
984 inline bool operator!=(const link& x, const link& y) {return !(x == y);}
|
|
ferencd@0
|
985 inline bool operator> (const link& x, const link& y) {return y < x;}
|
|
ferencd@0
|
986 inline bool operator<=(const link& x, const link& y) {return !(y < x);}
|
|
ferencd@0
|
987 inline bool operator>=(const link& x, const link& y) {return !(x < y);}
|
|
ferencd@0
|
988
|
|
ferencd@0
|
989 #endif // !USE_OS_TZDB
|
|
ferencd@0
|
990
|
|
ferencd@0
|
991 #if !MISSING_LEAP_SECONDS
|
|
ferencd@0
|
992
|
|
ferencd@0
|
993 class leap
|
|
ferencd@0
|
994 {
|
|
ferencd@0
|
995 private:
|
|
ferencd@0
|
996 sys_seconds date_;
|
|
ferencd@0
|
997
|
|
ferencd@0
|
998 public:
|
|
ferencd@0
|
999 #if USE_OS_TZDB
|
|
ferencd@0
|
1000 DATE_API explicit leap(const sys_seconds& s, detail::undocumented);
|
|
ferencd@0
|
1001 #else
|
|
ferencd@0
|
1002 DATE_API explicit leap(const std::string& s, detail::undocumented);
|
|
ferencd@0
|
1003 #endif
|
|
ferencd@0
|
1004
|
|
ferencd@0
|
1005 sys_seconds date() const {return date_;}
|
|
ferencd@0
|
1006
|
|
ferencd@0
|
1007 friend bool operator==(const leap& x, const leap& y) {return x.date_ == y.date_;}
|
|
ferencd@0
|
1008 friend bool operator< (const leap& x, const leap& y) {return x.date_ < y.date_;}
|
|
ferencd@0
|
1009
|
|
ferencd@0
|
1010 template <class Duration>
|
|
ferencd@0
|
1011 friend
|
|
ferencd@0
|
1012 bool
|
|
ferencd@0
|
1013 operator==(const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1014 {
|
|
ferencd@0
|
1015 return x.date_ == y;
|
|
ferencd@0
|
1016 }
|
|
ferencd@0
|
1017
|
|
ferencd@0
|
1018 template <class Duration>
|
|
ferencd@0
|
1019 friend
|
|
ferencd@0
|
1020 bool
|
|
ferencd@0
|
1021 operator< (const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1022 {
|
|
ferencd@0
|
1023 return x.date_ < y;
|
|
ferencd@0
|
1024 }
|
|
ferencd@0
|
1025
|
|
ferencd@0
|
1026 template <class Duration>
|
|
ferencd@0
|
1027 friend
|
|
ferencd@0
|
1028 bool
|
|
ferencd@0
|
1029 operator< (const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1030 {
|
|
ferencd@0
|
1031 return x < y.date_;
|
|
ferencd@0
|
1032 }
|
|
ferencd@0
|
1033
|
|
ferencd@0
|
1034 friend DATE_API std::ostream& operator<<(std::ostream& os, const leap& x);
|
|
ferencd@0
|
1035 };
|
|
ferencd@0
|
1036
|
|
ferencd@0
|
1037 inline bool operator!=(const leap& x, const leap& y) {return !(x == y);}
|
|
ferencd@0
|
1038 inline bool operator> (const leap& x, const leap& y) {return y < x;}
|
|
ferencd@0
|
1039 inline bool operator<=(const leap& x, const leap& y) {return !(y < x);}
|
|
ferencd@0
|
1040 inline bool operator>=(const leap& x, const leap& y) {return !(x < y);}
|
|
ferencd@0
|
1041
|
|
ferencd@0
|
1042 template <class Duration>
|
|
ferencd@0
|
1043 inline
|
|
ferencd@0
|
1044 bool
|
|
ferencd@0
|
1045 operator==(const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1046 {
|
|
ferencd@0
|
1047 return y == x;
|
|
ferencd@0
|
1048 }
|
|
ferencd@0
|
1049
|
|
ferencd@0
|
1050 template <class Duration>
|
|
ferencd@0
|
1051 inline
|
|
ferencd@0
|
1052 bool
|
|
ferencd@0
|
1053 operator!=(const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1054 {
|
|
ferencd@0
|
1055 return !(x == y);
|
|
ferencd@0
|
1056 }
|
|
ferencd@0
|
1057
|
|
ferencd@0
|
1058 template <class Duration>
|
|
ferencd@0
|
1059 inline
|
|
ferencd@0
|
1060 bool
|
|
ferencd@0
|
1061 operator!=(const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1062 {
|
|
ferencd@0
|
1063 return !(x == y);
|
|
ferencd@0
|
1064 }
|
|
ferencd@0
|
1065
|
|
ferencd@0
|
1066 template <class Duration>
|
|
ferencd@0
|
1067 inline
|
|
ferencd@0
|
1068 bool
|
|
ferencd@0
|
1069 operator> (const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1070 {
|
|
ferencd@0
|
1071 return y < x;
|
|
ferencd@0
|
1072 }
|
|
ferencd@0
|
1073
|
|
ferencd@0
|
1074 template <class Duration>
|
|
ferencd@0
|
1075 inline
|
|
ferencd@0
|
1076 bool
|
|
ferencd@0
|
1077 operator> (const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1078 {
|
|
ferencd@0
|
1079 return y < x;
|
|
ferencd@0
|
1080 }
|
|
ferencd@0
|
1081
|
|
ferencd@0
|
1082 template <class Duration>
|
|
ferencd@0
|
1083 inline
|
|
ferencd@0
|
1084 bool
|
|
ferencd@0
|
1085 operator<=(const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1086 {
|
|
ferencd@0
|
1087 return !(y < x);
|
|
ferencd@0
|
1088 }
|
|
ferencd@0
|
1089
|
|
ferencd@0
|
1090 template <class Duration>
|
|
ferencd@0
|
1091 inline
|
|
ferencd@0
|
1092 bool
|
|
ferencd@0
|
1093 operator<=(const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1094 {
|
|
ferencd@0
|
1095 return !(y < x);
|
|
ferencd@0
|
1096 }
|
|
ferencd@0
|
1097
|
|
ferencd@0
|
1098 template <class Duration>
|
|
ferencd@0
|
1099 inline
|
|
ferencd@0
|
1100 bool
|
|
ferencd@0
|
1101 operator>=(const leap& x, const sys_time<Duration>& y)
|
|
ferencd@0
|
1102 {
|
|
ferencd@0
|
1103 return !(x < y);
|
|
ferencd@0
|
1104 }
|
|
ferencd@0
|
1105
|
|
ferencd@0
|
1106 template <class Duration>
|
|
ferencd@0
|
1107 inline
|
|
ferencd@0
|
1108 bool
|
|
ferencd@0
|
1109 operator>=(const sys_time<Duration>& x, const leap& y)
|
|
ferencd@0
|
1110 {
|
|
ferencd@0
|
1111 return !(x < y);
|
|
ferencd@0
|
1112 }
|
|
ferencd@0
|
1113
|
|
ferencd@0
|
1114 #endif // !MISSING_LEAP_SECONDS
|
|
ferencd@0
|
1115
|
|
ferencd@0
|
1116 #ifdef _WIN32
|
|
ferencd@0
|
1117
|
|
ferencd@0
|
1118 namespace detail
|
|
ferencd@0
|
1119 {
|
|
ferencd@0
|
1120
|
|
ferencd@0
|
1121 // The time zone mapping is modelled after this data file:
|
|
ferencd@0
|
1122 // http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml
|
|
ferencd@0
|
1123 // and the field names match the element names from the mapZone element
|
|
ferencd@0
|
1124 // of windowsZones.xml.
|
|
ferencd@0
|
1125 // The website displays this file here:
|
|
ferencd@0
|
1126 // http://www.unicode.org/cldr/charts/latest/supplemental/zone_tzid.html
|
|
ferencd@0
|
1127 // The html view is sorted before being displayed but is otherwise the same
|
|
ferencd@0
|
1128 // There is a mapping between the os centric view (in this case windows)
|
|
ferencd@0
|
1129 // the html displays uses and the generic view the xml file.
|
|
ferencd@0
|
1130 // That mapping is this:
|
|
ferencd@0
|
1131 // display column "windows" -> xml field "other".
|
|
ferencd@0
|
1132 // display column "region" -> xml field "territory".
|
|
ferencd@0
|
1133 // display column "tzid" -> xml field "type".
|
|
ferencd@0
|
1134 // This structure uses the generic terminology because it could be
|
|
ferencd@0
|
1135 // used to to support other os/native name conversions, not just windows,
|
|
ferencd@0
|
1136 // and using the same generic names helps retain the connection to the
|
|
ferencd@0
|
1137 // origin of the data that we are using.
|
|
ferencd@0
|
1138 struct timezone_mapping
|
|
ferencd@0
|
1139 {
|
|
ferencd@0
|
1140 timezone_mapping(const char* other, const char* territory, const char* type)
|
|
ferencd@0
|
1141 : other(other), territory(territory), type(type)
|
|
ferencd@0
|
1142 {
|
|
ferencd@0
|
1143 }
|
|
ferencd@0
|
1144 timezone_mapping() = default;
|
|
ferencd@0
|
1145 std::string other;
|
|
ferencd@0
|
1146 std::string territory;
|
|
ferencd@0
|
1147 std::string type;
|
|
ferencd@0
|
1148 };
|
|
ferencd@0
|
1149
|
|
ferencd@0
|
1150 } // detail
|
|
ferencd@0
|
1151
|
|
ferencd@0
|
1152 #endif // _WIN32
|
|
ferencd@0
|
1153
|
|
ferencd@0
|
1154 struct tzdb
|
|
ferencd@0
|
1155 {
|
|
ferencd@0
|
1156 std::string version = "unknown";
|
|
ferencd@0
|
1157 std::vector<time_zone> zones;
|
|
ferencd@0
|
1158 #if !USE_OS_TZDB
|
|
ferencd@0
|
1159 std::vector<link> links;
|
|
ferencd@0
|
1160 #endif
|
|
ferencd@0
|
1161 #if !MISSING_LEAP_SECONDS
|
|
ferencd@0
|
1162 std::vector<leap> leaps;
|
|
ferencd@0
|
1163 #endif
|
|
ferencd@0
|
1164 #if !USE_OS_TZDB
|
|
ferencd@0
|
1165 std::vector<detail::Rule> rules;
|
|
ferencd@0
|
1166 #endif
|
|
ferencd@0
|
1167 #ifdef _WIN32
|
|
ferencd@0
|
1168 std::vector<detail::timezone_mapping> mappings;
|
|
ferencd@0
|
1169 #endif
|
|
ferencd@0
|
1170 tzdb* next = nullptr;
|
|
ferencd@0
|
1171
|
|
ferencd@0
|
1172 tzdb() = default;
|
|
ferencd@0
|
1173 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
|
|
ferencd@0
|
1174 tzdb(tzdb&&) = default;
|
|
ferencd@0
|
1175 tzdb& operator=(tzdb&&) = default;
|
|
ferencd@0
|
1176 #else // defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
1177 tzdb(tzdb&& src)
|
|
ferencd@0
|
1178 : version(std::move(src.version))
|
|
ferencd@0
|
1179 , zones(std::move(src.zones))
|
|
ferencd@0
|
1180 , links(std::move(src.links))
|
|
ferencd@0
|
1181 , leaps(std::move(src.leaps))
|
|
ferencd@0
|
1182 , rules(std::move(src.rules))
|
|
ferencd@0
|
1183 , mappings(std::move(src.mappings))
|
|
ferencd@0
|
1184 {}
|
|
ferencd@0
|
1185
|
|
ferencd@0
|
1186 tzdb& operator=(tzdb&& src)
|
|
ferencd@0
|
1187 {
|
|
ferencd@0
|
1188 version = std::move(src.version);
|
|
ferencd@0
|
1189 zones = std::move(src.zones);
|
|
ferencd@0
|
1190 links = std::move(src.links);
|
|
ferencd@0
|
1191 leaps = std::move(src.leaps);
|
|
ferencd@0
|
1192 rules = std::move(src.rules);
|
|
ferencd@0
|
1193 mappings = std::move(src.mappings);
|
|
ferencd@0
|
1194 return *this;
|
|
ferencd@0
|
1195 }
|
|
ferencd@0
|
1196 #endif // defined(_MSC_VER) && (_MSC_VER < 1900)
|
|
ferencd@0
|
1197
|
|
ferencd@0
|
1198 #if HAS_STRING_VIEW
|
|
ferencd@0
|
1199 const time_zone* locate_zone(std::string_view tz_name) const;
|
|
ferencd@0
|
1200 #else
|
|
ferencd@0
|
1201 const time_zone* locate_zone(const std::string& tz_name) const;
|
|
ferencd@0
|
1202 #endif
|
|
ferencd@0
|
1203 const time_zone* current_zone() const;
|
|
ferencd@0
|
1204 };
|
|
ferencd@0
|
1205
|
|
ferencd@0
|
1206 using TZ_DB = tzdb;
|
|
ferencd@0
|
1207
|
|
ferencd@0
|
1208 DATE_API std::ostream&
|
|
ferencd@0
|
1209 operator<<(std::ostream& os, const tzdb& db);
|
|
ferencd@0
|
1210
|
|
ferencd@0
|
1211 DATE_API const tzdb& get_tzdb();
|
|
ferencd@0
|
1212
|
|
ferencd@0
|
1213 class tzdb_list
|
|
ferencd@0
|
1214 {
|
|
ferencd@0
|
1215 std::atomic<tzdb*> head_{nullptr};
|
|
ferencd@0
|
1216
|
|
ferencd@0
|
1217 public:
|
|
ferencd@0
|
1218 ~tzdb_list();
|
|
ferencd@0
|
1219 tzdb_list() = default;
|
|
ferencd@0
|
1220 tzdb_list(tzdb_list&& x) noexcept;
|
|
ferencd@0
|
1221
|
|
ferencd@0
|
1222 const tzdb& front() const noexcept {return *head_;}
|
|
ferencd@0
|
1223 tzdb& front() noexcept {return *head_;}
|
|
ferencd@0
|
1224
|
|
ferencd@0
|
1225 class const_iterator;
|
|
ferencd@0
|
1226
|
|
ferencd@0
|
1227 const_iterator begin() const noexcept;
|
|
ferencd@0
|
1228 const_iterator end() const noexcept;
|
|
ferencd@0
|
1229
|
|
ferencd@0
|
1230 const_iterator cbegin() const noexcept;
|
|
ferencd@0
|
1231 const_iterator cend() const noexcept;
|
|
ferencd@0
|
1232
|
|
ferencd@0
|
1233 const_iterator erase_after(const_iterator p) noexcept;
|
|
ferencd@0
|
1234
|
|
ferencd@0
|
1235 struct undocumented_helper;
|
|
ferencd@0
|
1236 private:
|
|
ferencd@0
|
1237 void push_front(tzdb* tzdb) noexcept;
|
|
ferencd@0
|
1238 };
|
|
ferencd@0
|
1239
|
|
ferencd@0
|
1240 class tzdb_list::const_iterator
|
|
ferencd@0
|
1241 {
|
|
ferencd@0
|
1242 tzdb* p_ = nullptr;
|
|
ferencd@0
|
1243
|
|
ferencd@0
|
1244 explicit const_iterator(tzdb* p) noexcept : p_{p} {}
|
|
ferencd@0
|
1245 public:
|
|
ferencd@0
|
1246 const_iterator() = default;
|
|
ferencd@0
|
1247
|
|
ferencd@0
|
1248 using iterator_category = std::forward_iterator_tag;
|
|
ferencd@0
|
1249 using value_type = tzdb;
|
|
ferencd@0
|
1250 using reference = const value_type&;
|
|
ferencd@0
|
1251 using pointer = const value_type*;
|
|
ferencd@0
|
1252 using difference_type = std::ptrdiff_t;
|
|
ferencd@0
|
1253
|
|
ferencd@0
|
1254 reference operator*() const noexcept {return *p_;}
|
|
ferencd@0
|
1255 pointer operator->() const noexcept {return p_;}
|
|
ferencd@0
|
1256
|
|
ferencd@0
|
1257 const_iterator& operator++() noexcept {p_ = p_->next; return *this;}
|
|
ferencd@0
|
1258 const_iterator operator++(int) noexcept {auto t = *this; ++(*this); return t;}
|
|
ferencd@0
|
1259
|
|
ferencd@0
|
1260 friend
|
|
ferencd@0
|
1261 bool
|
|
ferencd@0
|
1262 operator==(const const_iterator& x, const const_iterator& y) noexcept
|
|
ferencd@0
|
1263 {return x.p_ == y.p_;}
|
|
ferencd@0
|
1264
|
|
ferencd@0
|
1265 friend
|
|
ferencd@0
|
1266 bool
|
|
ferencd@0
|
1267 operator!=(const const_iterator& x, const const_iterator& y) noexcept
|
|
ferencd@0
|
1268 {return !(x == y);}
|
|
ferencd@0
|
1269
|
|
ferencd@0
|
1270 friend class tzdb_list;
|
|
ferencd@0
|
1271 };
|
|
ferencd@0
|
1272
|
|
ferencd@0
|
1273 inline
|
|
ferencd@0
|
1274 tzdb_list::const_iterator
|
|
ferencd@0
|
1275 tzdb_list::begin() const noexcept
|
|
ferencd@0
|
1276 {
|
|
ferencd@0
|
1277 return const_iterator{head_};
|
|
ferencd@0
|
1278 }
|
|
ferencd@0
|
1279
|
|
ferencd@0
|
1280 inline
|
|
ferencd@0
|
1281 tzdb_list::const_iterator
|
|
ferencd@0
|
1282 tzdb_list::end() const noexcept
|
|
ferencd@0
|
1283 {
|
|
ferencd@0
|
1284 return const_iterator{nullptr};
|
|
ferencd@0
|
1285 }
|
|
ferencd@0
|
1286
|
|
ferencd@0
|
1287 inline
|
|
ferencd@0
|
1288 tzdb_list::const_iterator
|
|
ferencd@0
|
1289 tzdb_list::cbegin() const noexcept
|
|
ferencd@0
|
1290 {
|
|
ferencd@0
|
1291 return begin();
|
|
ferencd@0
|
1292 }
|
|
ferencd@0
|
1293
|
|
ferencd@0
|
1294 inline
|
|
ferencd@0
|
1295 tzdb_list::const_iterator
|
|
ferencd@0
|
1296 tzdb_list::cend() const noexcept
|
|
ferencd@0
|
1297 {
|
|
ferencd@0
|
1298 return end();
|
|
ferencd@0
|
1299 }
|
|
ferencd@0
|
1300
|
|
ferencd@0
|
1301 DATE_API tzdb_list& get_tzdb_list();
|
|
ferencd@0
|
1302
|
|
ferencd@0
|
1303 #if !USE_OS_TZDB
|
|
ferencd@0
|
1304
|
|
ferencd@0
|
1305 DATE_API const tzdb& reload_tzdb();
|
|
ferencd@0
|
1306 DATE_API void set_install(const std::string& install);
|
|
ferencd@0
|
1307
|
|
ferencd@0
|
1308 #endif // !USE_OS_TZDB
|
|
ferencd@0
|
1309
|
|
ferencd@0
|
1310 #if HAS_REMOTE_API
|
|
ferencd@0
|
1311
|
|
ferencd@0
|
1312 DATE_API std::string remote_version();
|
|
ferencd@0
|
1313 DATE_API bool remote_download(const std::string& version);
|
|
ferencd@0
|
1314 DATE_API bool remote_install(const std::string& version);
|
|
ferencd@0
|
1315
|
|
ferencd@0
|
1316 #endif
|
|
ferencd@0
|
1317
|
|
ferencd@0
|
1318 // zoned_time
|
|
ferencd@0
|
1319
|
|
ferencd@0
|
1320 namespace detail
|
|
ferencd@0
|
1321 {
|
|
ferencd@0
|
1322
|
|
ferencd@0
|
1323 template <class T>
|
|
ferencd@0
|
1324 inline
|
|
ferencd@0
|
1325 T*
|
|
ferencd@0
|
1326 to_raw_pointer(T* p) noexcept
|
|
ferencd@0
|
1327 {
|
|
ferencd@0
|
1328 return p;
|
|
ferencd@0
|
1329 }
|
|
ferencd@0
|
1330
|
|
ferencd@0
|
1331 template <class Pointer>
|
|
ferencd@0
|
1332 inline
|
|
ferencd@0
|
1333 auto
|
|
ferencd@0
|
1334 to_raw_pointer(Pointer p) noexcept
|
|
ferencd@0
|
1335 -> decltype(detail::to_raw_pointer(p.operator->()))
|
|
ferencd@0
|
1336 {
|
|
ferencd@0
|
1337 return detail::to_raw_pointer(p.operator->());
|
|
ferencd@0
|
1338 }
|
|
ferencd@0
|
1339
|
|
ferencd@0
|
1340 } // namespace detail
|
|
ferencd@0
|
1341
|
|
ferencd@0
|
1342 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1343 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1344 template <class T, class>
|
|
ferencd@0
|
1345 #endif
|
|
ferencd@0
|
1346 inline
|
|
ferencd@0
|
1347 zoned_time<Duration, TimeZonePtr>::zoned_time()
|
|
ferencd@0
|
1348 : zone_(zoned_traits<TimeZonePtr>::default_zone())
|
|
ferencd@0
|
1349 {}
|
|
ferencd@0
|
1350
|
|
ferencd@0
|
1351 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1352 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1353 template <class T, class>
|
|
ferencd@0
|
1354 #endif
|
|
ferencd@0
|
1355 inline
|
|
ferencd@0
|
1356 zoned_time<Duration, TimeZonePtr>::zoned_time(const sys_time<Duration>& st)
|
|
ferencd@0
|
1357 : zone_(zoned_traits<TimeZonePtr>::default_zone())
|
|
ferencd@0
|
1358 , tp_(st)
|
|
ferencd@0
|
1359 {}
|
|
ferencd@0
|
1360
|
|
ferencd@0
|
1361 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1362 inline
|
|
ferencd@0
|
1363 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z)
|
|
ferencd@0
|
1364 : zone_(std::move(z))
|
|
ferencd@0
|
1365 {assert(detail::to_raw_pointer(zone_) != nullptr);}
|
|
ferencd@0
|
1366
|
|
ferencd@0
|
1367 #if HAS_STRING_VIEW
|
|
ferencd@0
|
1368
|
|
ferencd@0
|
1369 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1370 template <class T, class>
|
|
ferencd@0
|
1371 inline
|
|
ferencd@0
|
1372 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name)
|
|
ferencd@0
|
1373 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name))
|
|
ferencd@0
|
1374 {}
|
|
ferencd@0
|
1375
|
|
ferencd@0
|
1376 #else // !HAS_STRING_VIEW
|
|
ferencd@0
|
1377
|
|
ferencd@0
|
1378 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1379 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1380 template <class T, class>
|
|
ferencd@0
|
1381 #endif
|
|
ferencd@0
|
1382 inline
|
|
ferencd@0
|
1383 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name)
|
|
ferencd@0
|
1384 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name))
|
|
ferencd@0
|
1385 {}
|
|
ferencd@0
|
1386
|
|
ferencd@0
|
1387 #endif // !HAS_STRING_VIEW
|
|
ferencd@0
|
1388
|
|
ferencd@0
|
1389 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1390 template <class Duration2, class>
|
|
ferencd@0
|
1391 inline
|
|
ferencd@0
|
1392 zoned_time<Duration, TimeZonePtr>::zoned_time(const zoned_time<Duration2, TimeZonePtr>& zt) NOEXCEPT
|
|
ferencd@0
|
1393 : zone_(zt.zone_)
|
|
ferencd@0
|
1394 , tp_(zt.tp_)
|
|
ferencd@0
|
1395 {}
|
|
ferencd@0
|
1396
|
|
ferencd@0
|
1397 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1398 inline
|
|
ferencd@0
|
1399 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z, const sys_time<Duration>& st)
|
|
ferencd@0
|
1400 : zone_(std::move(z))
|
|
ferencd@0
|
1401 , tp_(st)
|
|
ferencd@0
|
1402 {}
|
|
ferencd@0
|
1403
|
|
ferencd@0
|
1404 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1405 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1406 template <class T, class>
|
|
ferencd@0
|
1407 #endif
|
|
ferencd@0
|
1408 inline
|
|
ferencd@0
|
1409 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z, const local_time<Duration>& t)
|
|
ferencd@0
|
1410 : zone_(std::move(z))
|
|
ferencd@0
|
1411 , tp_(zone_->to_sys(t))
|
|
ferencd@0
|
1412 {}
|
|
ferencd@0
|
1413
|
|
ferencd@0
|
1414 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1415 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1416 template <class T, class>
|
|
ferencd@0
|
1417 #endif
|
|
ferencd@0
|
1418 inline
|
|
ferencd@0
|
1419 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z, const local_time<Duration>& t,
|
|
ferencd@0
|
1420 choose c)
|
|
ferencd@0
|
1421 : zone_(std::move(z))
|
|
ferencd@0
|
1422 , tp_(zone_->to_sys(t, c))
|
|
ferencd@0
|
1423 {}
|
|
ferencd@0
|
1424
|
|
ferencd@0
|
1425 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1426 template <class Duration2, class TimeZonePtr2, class>
|
|
ferencd@0
|
1427 inline
|
|
ferencd@0
|
1428 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z,
|
|
ferencd@0
|
1429 const zoned_time<Duration2, TimeZonePtr2>& zt)
|
|
ferencd@0
|
1430 : zone_(std::move(z))
|
|
ferencd@0
|
1431 , tp_(zt.tp_)
|
|
ferencd@0
|
1432 {}
|
|
ferencd@0
|
1433
|
|
ferencd@0
|
1434 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1435 template <class Duration2, class TimeZonePtr2, class>
|
|
ferencd@0
|
1436 inline
|
|
ferencd@0
|
1437 zoned_time<Duration, TimeZonePtr>::zoned_time(TimeZonePtr z,
|
|
ferencd@0
|
1438 const zoned_time<Duration2, TimeZonePtr2>& zt, choose)
|
|
ferencd@0
|
1439 : zoned_time(std::move(z), zt)
|
|
ferencd@0
|
1440 {}
|
|
ferencd@0
|
1441
|
|
ferencd@0
|
1442 #if HAS_STRING_VIEW
|
|
ferencd@0
|
1443
|
|
ferencd@0
|
1444 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1445 template <class T, class>
|
|
ferencd@0
|
1446 inline
|
|
ferencd@0
|
1447 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name,
|
|
ferencd@0
|
1448 detail::nodeduct_t<const sys_time<Duration>&> st)
|
|
ferencd@0
|
1449 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), st)
|
|
ferencd@0
|
1450 {}
|
|
ferencd@0
|
1451
|
|
ferencd@0
|
1452 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1453 template <class T, class>
|
|
ferencd@0
|
1454 inline
|
|
ferencd@0
|
1455 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name,
|
|
ferencd@0
|
1456 detail::nodeduct_t<const local_time<Duration>&> t)
|
|
ferencd@0
|
1457 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t)
|
|
ferencd@0
|
1458 {}
|
|
ferencd@0
|
1459
|
|
ferencd@0
|
1460 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1461 template <class T, class>
|
|
ferencd@0
|
1462 inline
|
|
ferencd@0
|
1463 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name,
|
|
ferencd@0
|
1464 detail::nodeduct_t<const local_time<Duration>&> t, choose c)
|
|
ferencd@0
|
1465 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t, c)
|
|
ferencd@0
|
1466 {}
|
|
ferencd@0
|
1467
|
|
ferencd@0
|
1468 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1469 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1470 inline
|
|
ferencd@0
|
1471 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name,
|
|
ferencd@0
|
1472 const zoned_time<Duration2, TimeZonePtr2>& zt)
|
|
ferencd@0
|
1473 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt)
|
|
ferencd@0
|
1474 {}
|
|
ferencd@0
|
1475
|
|
ferencd@0
|
1476 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1477 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1478 inline
|
|
ferencd@0
|
1479 zoned_time<Duration, TimeZonePtr>::zoned_time(std::string_view name,
|
|
ferencd@0
|
1480 const zoned_time<Duration2, TimeZonePtr2>& zt,
|
|
ferencd@0
|
1481 choose c)
|
|
ferencd@0
|
1482 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt, c)
|
|
ferencd@0
|
1483 {}
|
|
ferencd@0
|
1484
|
|
ferencd@0
|
1485 #else // !HAS_STRING_VIEW
|
|
ferencd@0
|
1486
|
|
ferencd@0
|
1487 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1488 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1489 template <class T, class>
|
|
ferencd@0
|
1490 #endif
|
|
ferencd@0
|
1491 inline
|
|
ferencd@0
|
1492 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name,
|
|
ferencd@0
|
1493 const sys_time<Duration>& st)
|
|
ferencd@0
|
1494 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), st)
|
|
ferencd@0
|
1495 {}
|
|
ferencd@0
|
1496
|
|
ferencd@0
|
1497 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1498 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1499 template <class T, class>
|
|
ferencd@0
|
1500 #endif
|
|
ferencd@0
|
1501 inline
|
|
ferencd@0
|
1502 zoned_time<Duration, TimeZonePtr>::zoned_time(const char* name,
|
|
ferencd@0
|
1503 const sys_time<Duration>& st)
|
|
ferencd@0
|
1504 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), st)
|
|
ferencd@0
|
1505 {}
|
|
ferencd@0
|
1506
|
|
ferencd@0
|
1507 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1508 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1509 template <class T, class>
|
|
ferencd@0
|
1510 #endif
|
|
ferencd@0
|
1511 inline
|
|
ferencd@0
|
1512 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name,
|
|
ferencd@0
|
1513 const local_time<Duration>& t)
|
|
ferencd@0
|
1514 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t)
|
|
ferencd@0
|
1515 {}
|
|
ferencd@0
|
1516
|
|
ferencd@0
|
1517 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1518 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1519 template <class T, class>
|
|
ferencd@0
|
1520 #endif
|
|
ferencd@0
|
1521 inline
|
|
ferencd@0
|
1522 zoned_time<Duration, TimeZonePtr>::zoned_time(const char* name,
|
|
ferencd@0
|
1523 const local_time<Duration>& t)
|
|
ferencd@0
|
1524 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t)
|
|
ferencd@0
|
1525 {}
|
|
ferencd@0
|
1526
|
|
ferencd@0
|
1527 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1528 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1529 template <class T, class>
|
|
ferencd@0
|
1530 #endif
|
|
ferencd@0
|
1531 inline
|
|
ferencd@0
|
1532 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name,
|
|
ferencd@0
|
1533 const local_time<Duration>& t, choose c)
|
|
ferencd@0
|
1534 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t, c)
|
|
ferencd@0
|
1535 {}
|
|
ferencd@0
|
1536
|
|
ferencd@0
|
1537 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1538 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1539 template <class T, class>
|
|
ferencd@0
|
1540 #endif
|
|
ferencd@0
|
1541 inline
|
|
ferencd@0
|
1542 zoned_time<Duration, TimeZonePtr>::zoned_time(const char* name,
|
|
ferencd@0
|
1543 const local_time<Duration>& t, choose c)
|
|
ferencd@0
|
1544 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), t, c)
|
|
ferencd@0
|
1545 {}
|
|
ferencd@0
|
1546
|
|
ferencd@0
|
1547 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1548 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1549 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1550 #else
|
|
ferencd@0
|
1551 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
1552 #endif
|
|
ferencd@0
|
1553 inline
|
|
ferencd@0
|
1554 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name,
|
|
ferencd@0
|
1555 const zoned_time<Duration2, TimeZonePtr2>& zt)
|
|
ferencd@0
|
1556 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt)
|
|
ferencd@0
|
1557 {}
|
|
ferencd@0
|
1558
|
|
ferencd@0
|
1559 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1560 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1561 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1562 #else
|
|
ferencd@0
|
1563 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
1564 #endif
|
|
ferencd@0
|
1565 inline
|
|
ferencd@0
|
1566 zoned_time<Duration, TimeZonePtr>::zoned_time(const char* name,
|
|
ferencd@0
|
1567 const zoned_time<Duration2, TimeZonePtr2>& zt)
|
|
ferencd@0
|
1568 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt)
|
|
ferencd@0
|
1569 {}
|
|
ferencd@0
|
1570
|
|
ferencd@0
|
1571 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1572 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1573 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1574 #else
|
|
ferencd@0
|
1575 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
1576 #endif
|
|
ferencd@0
|
1577 inline
|
|
ferencd@0
|
1578 zoned_time<Duration, TimeZonePtr>::zoned_time(const std::string& name,
|
|
ferencd@0
|
1579 const zoned_time<Duration2, TimeZonePtr2>& zt,
|
|
ferencd@0
|
1580 choose c)
|
|
ferencd@0
|
1581 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt, c)
|
|
ferencd@0
|
1582 {}
|
|
ferencd@0
|
1583
|
|
ferencd@0
|
1584 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1585 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1586 template <class Duration2, class TimeZonePtr2, class, class>
|
|
ferencd@0
|
1587 #else
|
|
ferencd@0
|
1588 template <class Duration2, class TimeZonePtr2>
|
|
ferencd@0
|
1589 #endif
|
|
ferencd@0
|
1590 inline
|
|
ferencd@0
|
1591 zoned_time<Duration, TimeZonePtr>::zoned_time(const char* name,
|
|
ferencd@0
|
1592 const zoned_time<Duration2, TimeZonePtr2>& zt,
|
|
ferencd@0
|
1593 choose c)
|
|
ferencd@0
|
1594 : zoned_time(zoned_traits<TimeZonePtr>::locate_zone(name), zt, c)
|
|
ferencd@0
|
1595 {}
|
|
ferencd@0
|
1596
|
|
ferencd@0
|
1597 #endif // HAS_STRING_VIEW
|
|
ferencd@0
|
1598
|
|
ferencd@0
|
1599 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1600 inline
|
|
ferencd@0
|
1601 zoned_time<Duration, TimeZonePtr>&
|
|
ferencd@0
|
1602 zoned_time<Duration, TimeZonePtr>::operator=(const sys_time<Duration>& st)
|
|
ferencd@0
|
1603 {
|
|
ferencd@0
|
1604 tp_ = st;
|
|
ferencd@0
|
1605 return *this;
|
|
ferencd@0
|
1606 }
|
|
ferencd@0
|
1607
|
|
ferencd@0
|
1608 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1609 inline
|
|
ferencd@0
|
1610 zoned_time<Duration, TimeZonePtr>&
|
|
ferencd@0
|
1611 zoned_time<Duration, TimeZonePtr>::operator=(const local_time<Duration>& ut)
|
|
ferencd@0
|
1612 {
|
|
ferencd@0
|
1613 tp_ = zone_->to_sys(ut);
|
|
ferencd@0
|
1614 return *this;
|
|
ferencd@0
|
1615 }
|
|
ferencd@0
|
1616
|
|
ferencd@0
|
1617 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1618 inline
|
|
ferencd@0
|
1619 zoned_time<Duration, TimeZonePtr>::operator local_time<typename zoned_time<Duration, TimeZonePtr>::duration>() const
|
|
ferencd@0
|
1620 {
|
|
ferencd@0
|
1621 return get_local_time();
|
|
ferencd@0
|
1622 }
|
|
ferencd@0
|
1623
|
|
ferencd@0
|
1624 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1625 inline
|
|
ferencd@0
|
1626 zoned_time<Duration, TimeZonePtr>::operator sys_time<typename zoned_time<Duration, TimeZonePtr>::duration>() const
|
|
ferencd@0
|
1627 {
|
|
ferencd@0
|
1628 return get_sys_time();
|
|
ferencd@0
|
1629 }
|
|
ferencd@0
|
1630
|
|
ferencd@0
|
1631 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1632 inline
|
|
ferencd@0
|
1633 TimeZonePtr
|
|
ferencd@0
|
1634 zoned_time<Duration, TimeZonePtr>::get_time_zone() const
|
|
ferencd@0
|
1635 {
|
|
ferencd@0
|
1636 return zone_;
|
|
ferencd@0
|
1637 }
|
|
ferencd@0
|
1638
|
|
ferencd@0
|
1639 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1640 inline
|
|
ferencd@0
|
1641 local_time<typename zoned_time<Duration, TimeZonePtr>::duration>
|
|
ferencd@0
|
1642 zoned_time<Duration, TimeZonePtr>::get_local_time() const
|
|
ferencd@0
|
1643 {
|
|
ferencd@0
|
1644 return zone_->to_local(tp_);
|
|
ferencd@0
|
1645 }
|
|
ferencd@0
|
1646
|
|
ferencd@0
|
1647 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1648 inline
|
|
ferencd@0
|
1649 sys_time<typename zoned_time<Duration, TimeZonePtr>::duration>
|
|
ferencd@0
|
1650 zoned_time<Duration, TimeZonePtr>::get_sys_time() const
|
|
ferencd@0
|
1651 {
|
|
ferencd@0
|
1652 return tp_;
|
|
ferencd@0
|
1653 }
|
|
ferencd@0
|
1654
|
|
ferencd@0
|
1655 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1656 inline
|
|
ferencd@0
|
1657 sys_info
|
|
ferencd@0
|
1658 zoned_time<Duration, TimeZonePtr>::get_info() const
|
|
ferencd@0
|
1659 {
|
|
ferencd@0
|
1660 return zone_->get_info(tp_);
|
|
ferencd@0
|
1661 }
|
|
ferencd@0
|
1662
|
|
ferencd@0
|
1663 // make_zoned_time
|
|
ferencd@0
|
1664
|
|
ferencd@0
|
1665 inline
|
|
ferencd@0
|
1666 zoned_time<std::chrono::seconds>
|
|
ferencd@0
|
1667 make_zoned()
|
|
ferencd@0
|
1668 {
|
|
ferencd@0
|
1669 return zoned_time<std::chrono::seconds>();
|
|
ferencd@0
|
1670 }
|
|
ferencd@0
|
1671
|
|
ferencd@0
|
1672 template <class Duration>
|
|
ferencd@0
|
1673 inline
|
|
ferencd@0
|
1674 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1675 make_zoned(const sys_time<Duration>& tp)
|
|
ferencd@0
|
1676 {
|
|
ferencd@0
|
1677 return zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>(tp);
|
|
ferencd@0
|
1678 }
|
|
ferencd@0
|
1679
|
|
ferencd@0
|
1680 template <class TimeZonePtr
|
|
ferencd@0
|
1681 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1682 , class = typename std::enable_if
|
|
ferencd@0
|
1683 <
|
|
ferencd@0
|
1684 std::is_class
|
|
ferencd@0
|
1685 <
|
|
ferencd@0
|
1686 typename std::decay
|
|
ferencd@0
|
1687 <
|
|
ferencd@0
|
1688 decltype(*detail::to_raw_pointer(std::declval<TimeZonePtr&>()))
|
|
ferencd@0
|
1689 >::type
|
|
ferencd@0
|
1690 >{}
|
|
ferencd@0
|
1691 >::type
|
|
ferencd@0
|
1692 #endif
|
|
ferencd@0
|
1693 >
|
|
ferencd@0
|
1694 inline
|
|
ferencd@0
|
1695 zoned_time<std::chrono::seconds, TimeZonePtr>
|
|
ferencd@0
|
1696 make_zoned(TimeZonePtr z)
|
|
ferencd@0
|
1697 {
|
|
ferencd@0
|
1698 return zoned_time<std::chrono::seconds, TimeZonePtr>(std::move(z));
|
|
ferencd@0
|
1699 }
|
|
ferencd@0
|
1700
|
|
ferencd@0
|
1701 inline
|
|
ferencd@0
|
1702 zoned_seconds
|
|
ferencd@0
|
1703 make_zoned(const std::string& name)
|
|
ferencd@0
|
1704 {
|
|
ferencd@0
|
1705 return zoned_seconds(name);
|
|
ferencd@0
|
1706 }
|
|
ferencd@0
|
1707
|
|
ferencd@0
|
1708 template <class Duration, class TimeZonePtr
|
|
ferencd@0
|
1709 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1710 , class = typename std::enable_if
|
|
ferencd@0
|
1711 <
|
|
ferencd@0
|
1712 std::is_class<typename std::decay<decltype(*std::declval<TimeZonePtr&>())>::type>{}
|
|
ferencd@0
|
1713 >::type
|
|
ferencd@0
|
1714 #endif
|
|
ferencd@0
|
1715 >
|
|
ferencd@0
|
1716 inline
|
|
ferencd@0
|
1717 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type, TimeZonePtr>
|
|
ferencd@0
|
1718 make_zoned(TimeZonePtr zone, const local_time<Duration>& tp)
|
|
ferencd@0
|
1719 {
|
|
ferencd@0
|
1720 return zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type,
|
|
ferencd@0
|
1721 TimeZonePtr>(std::move(zone), tp);
|
|
ferencd@0
|
1722 }
|
|
ferencd@0
|
1723
|
|
ferencd@0
|
1724 template <class Duration, class TimeZonePtr
|
|
ferencd@0
|
1725 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1726 , class = typename std::enable_if
|
|
ferencd@0
|
1727 <
|
|
ferencd@0
|
1728 std::is_class<typename std::decay<decltype(*std::declval<TimeZonePtr&>())>::type>{}
|
|
ferencd@0
|
1729 >::type
|
|
ferencd@0
|
1730 #endif
|
|
ferencd@0
|
1731 >
|
|
ferencd@0
|
1732 inline
|
|
ferencd@0
|
1733 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type, TimeZonePtr>
|
|
ferencd@0
|
1734 make_zoned(TimeZonePtr zone, const local_time<Duration>& tp, choose c)
|
|
ferencd@0
|
1735 {
|
|
ferencd@0
|
1736 return zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type,
|
|
ferencd@0
|
1737 TimeZonePtr>(std::move(zone), tp, c);
|
|
ferencd@0
|
1738 }
|
|
ferencd@0
|
1739
|
|
ferencd@0
|
1740 template <class Duration>
|
|
ferencd@0
|
1741 inline
|
|
ferencd@0
|
1742 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1743 make_zoned(const std::string& name, const local_time<Duration>& tp)
|
|
ferencd@0
|
1744 {
|
|
ferencd@0
|
1745 return zoned_time<typename std::common_type<Duration,
|
|
ferencd@0
|
1746 std::chrono::seconds>::type>(name, tp);
|
|
ferencd@0
|
1747 }
|
|
ferencd@0
|
1748
|
|
ferencd@0
|
1749 template <class Duration>
|
|
ferencd@0
|
1750 inline
|
|
ferencd@0
|
1751 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1752 make_zoned(const std::string& name, const local_time<Duration>& tp, choose c)
|
|
ferencd@0
|
1753 {
|
|
ferencd@0
|
1754 return zoned_time<typename std::common_type<Duration,
|
|
ferencd@0
|
1755 std::chrono::seconds>::type>(name, tp, c);
|
|
ferencd@0
|
1756 }
|
|
ferencd@0
|
1757
|
|
ferencd@0
|
1758 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1759 inline
|
|
ferencd@0
|
1760 zoned_time<Duration, TimeZonePtr>
|
|
ferencd@0
|
1761 make_zoned(TimeZonePtr zone, const zoned_time<Duration, TimeZonePtr>& zt)
|
|
ferencd@0
|
1762 {
|
|
ferencd@0
|
1763 return zoned_time<Duration, TimeZonePtr>(std::move(zone), zt);
|
|
ferencd@0
|
1764 }
|
|
ferencd@0
|
1765
|
|
ferencd@0
|
1766 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1767 inline
|
|
ferencd@0
|
1768 zoned_time<Duration, TimeZonePtr>
|
|
ferencd@0
|
1769 make_zoned(const std::string& name, const zoned_time<Duration, TimeZonePtr>& zt)
|
|
ferencd@0
|
1770 {
|
|
ferencd@0
|
1771 return zoned_time<Duration, TimeZonePtr>(name, zt);
|
|
ferencd@0
|
1772 }
|
|
ferencd@0
|
1773
|
|
ferencd@0
|
1774 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1775 inline
|
|
ferencd@0
|
1776 zoned_time<Duration, TimeZonePtr>
|
|
ferencd@0
|
1777 make_zoned(TimeZonePtr zone, const zoned_time<Duration, TimeZonePtr>& zt, choose c)
|
|
ferencd@0
|
1778 {
|
|
ferencd@0
|
1779 return zoned_time<Duration, TimeZonePtr>(std::move(zone), zt, c);
|
|
ferencd@0
|
1780 }
|
|
ferencd@0
|
1781
|
|
ferencd@0
|
1782 template <class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1783 inline
|
|
ferencd@0
|
1784 zoned_time<Duration, TimeZonePtr>
|
|
ferencd@0
|
1785 make_zoned(const std::string& name, const zoned_time<Duration, TimeZonePtr>& zt, choose c)
|
|
ferencd@0
|
1786 {
|
|
ferencd@0
|
1787 return zoned_time<Duration, TimeZonePtr>(name, zt, c);
|
|
ferencd@0
|
1788 }
|
|
ferencd@0
|
1789
|
|
ferencd@0
|
1790 template <class Duration, class TimeZonePtr
|
|
ferencd@0
|
1791 #if !defined(_MSC_VER) || (_MSC_VER > 1900)
|
|
ferencd@0
|
1792 , class = typename std::enable_if
|
|
ferencd@0
|
1793 <
|
|
ferencd@0
|
1794 std::is_class<typename std::decay<decltype(*std::declval<TimeZonePtr&>())>::type>{}
|
|
ferencd@0
|
1795 >::type
|
|
ferencd@0
|
1796 #endif
|
|
ferencd@0
|
1797 >
|
|
ferencd@0
|
1798 inline
|
|
ferencd@0
|
1799 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type, TimeZonePtr>
|
|
ferencd@0
|
1800 make_zoned(TimeZonePtr zone, const sys_time<Duration>& st)
|
|
ferencd@0
|
1801 {
|
|
ferencd@0
|
1802 return zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type,
|
|
ferencd@0
|
1803 TimeZonePtr>(std::move(zone), st);
|
|
ferencd@0
|
1804 }
|
|
ferencd@0
|
1805
|
|
ferencd@0
|
1806 template <class Duration>
|
|
ferencd@0
|
1807 inline
|
|
ferencd@0
|
1808 zoned_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1809 make_zoned(const std::string& name, const sys_time<Duration>& st)
|
|
ferencd@0
|
1810 {
|
|
ferencd@0
|
1811 return zoned_time<typename std::common_type<Duration,
|
|
ferencd@0
|
1812 std::chrono::seconds>::type>(name, st);
|
|
ferencd@0
|
1813 }
|
|
ferencd@0
|
1814
|
|
ferencd@0
|
1815 template <class CharT, class Traits, class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1816 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
1817 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
ferencd@0
|
1818 const zoned_time<Duration, TimeZonePtr>& tp)
|
|
ferencd@0
|
1819 {
|
|
ferencd@0
|
1820 using duration = typename zoned_time<Duration, TimeZonePtr>::duration;
|
|
ferencd@0
|
1821 using LT = local_time<duration>;
|
|
ferencd@0
|
1822 auto const st = tp.get_sys_time();
|
|
ferencd@0
|
1823 auto const info = tp.get_time_zone()->get_info(st);
|
|
ferencd@0
|
1824 return to_stream(os, fmt, LT{(st+info.offset).time_since_epoch()},
|
|
ferencd@0
|
1825 &info.abbrev, &info.offset);
|
|
ferencd@0
|
1826 }
|
|
ferencd@0
|
1827
|
|
ferencd@0
|
1828 template <class CharT, class Traits, class Duration, class TimeZonePtr>
|
|
ferencd@0
|
1829 inline
|
|
ferencd@0
|
1830 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
1831 operator<<(std::basic_ostream<CharT, Traits>& os, const zoned_time<Duration, TimeZonePtr>& t)
|
|
ferencd@0
|
1832 {
|
|
ferencd@0
|
1833 const CharT fmt[] = {'%', 'F', ' ', '%', 'T', ' ', '%', 'Z', CharT{}};
|
|
ferencd@0
|
1834 return to_stream(os, fmt, t);
|
|
ferencd@0
|
1835 }
|
|
ferencd@0
|
1836
|
|
ferencd@0
|
1837 #if !MISSING_LEAP_SECONDS
|
|
ferencd@0
|
1838
|
|
ferencd@0
|
1839 class utc_clock
|
|
ferencd@0
|
1840 {
|
|
ferencd@0
|
1841 public:
|
|
ferencd@0
|
1842 using duration = std::chrono::system_clock::duration;
|
|
ferencd@0
|
1843 using rep = duration::rep;
|
|
ferencd@0
|
1844 using period = duration::period;
|
|
ferencd@0
|
1845 using time_point = std::chrono::time_point<utc_clock>;
|
|
ferencd@0
|
1846 static CONSTDATA bool is_steady = false;
|
|
ferencd@0
|
1847
|
|
ferencd@0
|
1848 static time_point now();
|
|
ferencd@0
|
1849
|
|
ferencd@0
|
1850 template<typename Duration>
|
|
ferencd@0
|
1851 static
|
|
ferencd@0
|
1852 std::chrono::time_point<std::chrono::system_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1853 to_sys(const std::chrono::time_point<utc_clock, Duration>&);
|
|
ferencd@0
|
1854
|
|
ferencd@0
|
1855 template<typename Duration>
|
|
ferencd@0
|
1856 static
|
|
ferencd@0
|
1857 std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1858 from_sys(const std::chrono::time_point<std::chrono::system_clock, Duration>&);
|
|
ferencd@0
|
1859
|
|
ferencd@0
|
1860 template<typename Duration>
|
|
ferencd@0
|
1861 static
|
|
ferencd@0
|
1862 std::chrono::time_point<local_t, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1863 to_local(const std::chrono::time_point<utc_clock, Duration>&);
|
|
ferencd@0
|
1864
|
|
ferencd@0
|
1865 template<typename Duration>
|
|
ferencd@0
|
1866 static
|
|
ferencd@0
|
1867 std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1868 from_local(const std::chrono::time_point<local_t, Duration>&);
|
|
ferencd@0
|
1869 };
|
|
ferencd@0
|
1870
|
|
ferencd@0
|
1871 template <class Duration>
|
|
ferencd@0
|
1872 using utc_time = std::chrono::time_point<utc_clock, Duration>;
|
|
ferencd@0
|
1873
|
|
ferencd@0
|
1874 using utc_seconds = utc_time<std::chrono::seconds>;
|
|
ferencd@0
|
1875
|
|
ferencd@0
|
1876 template <class Duration>
|
|
ferencd@0
|
1877 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1878 utc_clock::from_sys(const sys_time<Duration>& st)
|
|
ferencd@0
|
1879 {
|
|
ferencd@0
|
1880 using std::chrono::seconds;
|
|
ferencd@0
|
1881 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
1882 auto const& leaps = get_tzdb().leaps;
|
|
ferencd@0
|
1883 auto const lt = std::upper_bound(leaps.begin(), leaps.end(), st);
|
|
ferencd@0
|
1884 return utc_time<CD>{st.time_since_epoch() + seconds{lt-leaps.begin()}};
|
|
ferencd@0
|
1885 }
|
|
ferencd@0
|
1886
|
|
ferencd@0
|
1887 // Return pair<is_leap_second, seconds{number_of_leap_seconds_since_1970}>
|
|
ferencd@0
|
1888 // first is true if ut is during a leap second insertion, otherwise false.
|
|
ferencd@0
|
1889 // If ut is during a leap second insertion, that leap second is included in the count
|
|
ferencd@0
|
1890 template <class Duration>
|
|
ferencd@0
|
1891 std::pair<bool, std::chrono::seconds>
|
|
ferencd@0
|
1892 is_leap_second(date::utc_time<Duration> const& ut)
|
|
ferencd@0
|
1893 {
|
|
ferencd@0
|
1894 using std::chrono::seconds;
|
|
ferencd@0
|
1895 using duration = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
1896 auto const& leaps = get_tzdb().leaps;
|
|
ferencd@0
|
1897 auto tp = sys_time<duration>{ut.time_since_epoch()};
|
|
ferencd@0
|
1898 auto const lt = std::upper_bound(leaps.begin(), leaps.end(), tp);
|
|
ferencd@0
|
1899 auto ds = seconds{lt-leaps.begin()};
|
|
ferencd@0
|
1900 tp -= ds;
|
|
ferencd@0
|
1901 auto ls = false;
|
|
ferencd@0
|
1902 if (lt > leaps.begin())
|
|
ferencd@0
|
1903 {
|
|
ferencd@0
|
1904 if (tp < lt[-1])
|
|
ferencd@0
|
1905 {
|
|
ferencd@0
|
1906 if (tp >= lt[-1].date() - seconds{1})
|
|
ferencd@0
|
1907 ls = true;
|
|
ferencd@0
|
1908 else
|
|
ferencd@0
|
1909 --ds;
|
|
ferencd@0
|
1910 }
|
|
ferencd@0
|
1911 }
|
|
ferencd@0
|
1912 return {ls, ds};
|
|
ferencd@0
|
1913 }
|
|
ferencd@0
|
1914
|
|
ferencd@0
|
1915 struct leap_second_info
|
|
ferencd@0
|
1916 {
|
|
ferencd@0
|
1917 bool is_leap_second;
|
|
ferencd@0
|
1918 std::chrono::seconds elapsed;
|
|
ferencd@0
|
1919 };
|
|
ferencd@0
|
1920
|
|
ferencd@0
|
1921 template <class Duration>
|
|
ferencd@0
|
1922 leap_second_info
|
|
ferencd@0
|
1923 get_leap_second_info(date::utc_time<Duration> const& ut)
|
|
ferencd@0
|
1924 {
|
|
ferencd@0
|
1925 auto p = is_leap_second(ut);
|
|
ferencd@0
|
1926 return {p.first, p.second};
|
|
ferencd@0
|
1927 }
|
|
ferencd@0
|
1928
|
|
ferencd@0
|
1929 template <class Duration>
|
|
ferencd@0
|
1930 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1931 utc_clock::to_sys(const utc_time<Duration>& ut)
|
|
ferencd@0
|
1932 {
|
|
ferencd@0
|
1933 using std::chrono::seconds;
|
|
ferencd@0
|
1934 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
1935 auto ls = is_leap_second(ut);
|
|
ferencd@0
|
1936 auto tp = sys_time<CD>{ut.time_since_epoch() - ls.second};
|
|
ferencd@0
|
1937 if (ls.first)
|
|
ferencd@0
|
1938 tp = floor<seconds>(tp) + seconds{1} - CD{1};
|
|
ferencd@0
|
1939 return tp;
|
|
ferencd@0
|
1940 }
|
|
ferencd@0
|
1941
|
|
ferencd@0
|
1942 inline
|
|
ferencd@0
|
1943 utc_clock::time_point
|
|
ferencd@0
|
1944 utc_clock::now()
|
|
ferencd@0
|
1945 {
|
|
ferencd@0
|
1946 return from_sys(std::chrono::system_clock::now());
|
|
ferencd@0
|
1947 }
|
|
ferencd@0
|
1948
|
|
ferencd@0
|
1949 template <class Duration>
|
|
ferencd@0
|
1950 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1951 utc_clock::from_local(const local_time<Duration>& st)
|
|
ferencd@0
|
1952 {
|
|
ferencd@0
|
1953 return from_sys(sys_time<Duration>{st.time_since_epoch()});
|
|
ferencd@0
|
1954 }
|
|
ferencd@0
|
1955
|
|
ferencd@0
|
1956 template <class Duration>
|
|
ferencd@0
|
1957 local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
1958 utc_clock::to_local(const utc_time<Duration>& ut)
|
|
ferencd@0
|
1959 {
|
|
ferencd@0
|
1960 using CD = typename std::common_type<Duration, std::chrono::seconds>::type;
|
|
ferencd@0
|
1961 return local_time<CD>{to_sys(ut).time_since_epoch()};
|
|
ferencd@0
|
1962 }
|
|
ferencd@0
|
1963
|
|
ferencd@0
|
1964 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
1965 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
1966 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
ferencd@0
|
1967 const utc_time<Duration>& t)
|
|
ferencd@0
|
1968 {
|
|
ferencd@0
|
1969 using std::chrono::seconds;
|
|
ferencd@0
|
1970 using CT = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
1971 const std::string abbrev("UTC");
|
|
ferencd@0
|
1972 CONSTDATA seconds offset{0};
|
|
ferencd@0
|
1973 auto ls = is_leap_second(t);
|
|
ferencd@0
|
1974 auto tp = sys_time<CT>{t.time_since_epoch() - ls.second};
|
|
ferencd@0
|
1975 auto const sd = floor<days>(tp);
|
|
ferencd@0
|
1976 year_month_day ymd = sd;
|
|
ferencd@0
|
1977 auto time = make_time(tp - sys_seconds{sd});
|
|
ferencd@0
|
1978 time.seconds(detail::undocumented{}) += seconds{ls.first};
|
|
ferencd@0
|
1979 fields<CT> fds{ymd, time};
|
|
ferencd@0
|
1980 return to_stream(os, fmt, fds, &abbrev, &offset);
|
|
ferencd@0
|
1981 }
|
|
ferencd@0
|
1982
|
|
ferencd@0
|
1983 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
1984 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
1985 operator<<(std::basic_ostream<CharT, Traits>& os, const utc_time<Duration>& t)
|
|
ferencd@0
|
1986 {
|
|
ferencd@0
|
1987 const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}};
|
|
ferencd@0
|
1988 return to_stream(os, fmt, t);
|
|
ferencd@0
|
1989 }
|
|
ferencd@0
|
1990
|
|
ferencd@0
|
1991 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
ferencd@0
|
1992 std::basic_istream<CharT, Traits>&
|
|
ferencd@0
|
1993 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
ferencd@0
|
1994 utc_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
ferencd@0
|
1995 std::chrono::minutes* offset = nullptr)
|
|
ferencd@0
|
1996 {
|
|
ferencd@0
|
1997 using std::chrono::seconds;
|
|
ferencd@0
|
1998 using std::chrono::minutes;
|
|
ferencd@0
|
1999 using CT = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
2000 minutes offset_local{};
|
|
ferencd@0
|
2001 auto offptr = offset ? offset : &offset_local;
|
|
ferencd@0
|
2002 fields<CT> fds{};
|
|
ferencd@0
|
2003 fds.has_tod = true;
|
|
ferencd@0
|
2004 from_stream(is, fmt, fds, abbrev, offptr);
|
|
ferencd@0
|
2005 if (!fds.ymd.ok())
|
|
ferencd@0
|
2006 is.setstate(std::ios::failbit);
|
|
ferencd@0
|
2007 if (!is.fail())
|
|
ferencd@0
|
2008 {
|
|
ferencd@0
|
2009 bool is_60_sec = fds.tod.seconds() == seconds{60};
|
|
ferencd@0
|
2010 if (is_60_sec)
|
|
ferencd@0
|
2011 fds.tod.seconds(detail::undocumented{}) -= seconds{1};
|
|
ferencd@0
|
2012 auto tmp = utc_clock::from_sys(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
|
|
ferencd@0
|
2013 if (is_60_sec)
|
|
ferencd@0
|
2014 tmp += seconds{1};
|
|
ferencd@0
|
2015 if (is_60_sec != is_leap_second(tmp).first || !fds.tod.in_conventional_range())
|
|
ferencd@0
|
2016 {
|
|
ferencd@0
|
2017 is.setstate(std::ios::failbit);
|
|
ferencd@0
|
2018 return is;
|
|
ferencd@0
|
2019 }
|
|
ferencd@0
|
2020 tp = std::chrono::time_point_cast<Duration>(tmp);
|
|
ferencd@0
|
2021 }
|
|
ferencd@0
|
2022 return is;
|
|
ferencd@0
|
2023 }
|
|
ferencd@0
|
2024
|
|
ferencd@0
|
2025 // tai_clock
|
|
ferencd@0
|
2026
|
|
ferencd@0
|
2027 class tai_clock
|
|
ferencd@0
|
2028 {
|
|
ferencd@0
|
2029 public:
|
|
ferencd@0
|
2030 using duration = std::chrono::system_clock::duration;
|
|
ferencd@0
|
2031 using rep = duration::rep;
|
|
ferencd@0
|
2032 using period = duration::period;
|
|
ferencd@0
|
2033 using time_point = std::chrono::time_point<tai_clock>;
|
|
ferencd@0
|
2034 static const bool is_steady = false;
|
|
ferencd@0
|
2035
|
|
ferencd@0
|
2036 static time_point now();
|
|
ferencd@0
|
2037
|
|
ferencd@0
|
2038 template<typename Duration>
|
|
ferencd@0
|
2039 static
|
|
ferencd@0
|
2040 std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2041 to_utc(const std::chrono::time_point<tai_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2042
|
|
ferencd@0
|
2043 template<typename Duration>
|
|
ferencd@0
|
2044 static
|
|
ferencd@0
|
2045 std::chrono::time_point<tai_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2046 from_utc(const std::chrono::time_point<utc_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2047
|
|
ferencd@0
|
2048 template<typename Duration>
|
|
ferencd@0
|
2049 static
|
|
ferencd@0
|
2050 std::chrono::time_point<local_t, typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2051 to_local(const std::chrono::time_point<tai_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2052
|
|
ferencd@0
|
2053 template<typename Duration>
|
|
ferencd@0
|
2054 static
|
|
ferencd@0
|
2055 std::chrono::time_point<tai_clock, typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2056 from_local(const std::chrono::time_point<local_t, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2057 };
|
|
ferencd@0
|
2058
|
|
ferencd@0
|
2059 template <class Duration>
|
|
ferencd@0
|
2060 using tai_time = std::chrono::time_point<tai_clock, Duration>;
|
|
ferencd@0
|
2061
|
|
ferencd@0
|
2062 using tai_seconds = tai_time<std::chrono::seconds>;
|
|
ferencd@0
|
2063
|
|
ferencd@0
|
2064 template <class Duration>
|
|
ferencd@0
|
2065 inline
|
|
ferencd@0
|
2066 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2067 tai_clock::to_utc(const tai_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2068 {
|
|
ferencd@0
|
2069 using std::chrono::seconds;
|
|
ferencd@0
|
2070 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
2071 return utc_time<CD>{t.time_since_epoch()} -
|
|
ferencd@0
|
2072 (sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1) + seconds{10});
|
|
ferencd@0
|
2073 }
|
|
ferencd@0
|
2074
|
|
ferencd@0
|
2075 template <class Duration>
|
|
ferencd@0
|
2076 inline
|
|
ferencd@0
|
2077 tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2078 tai_clock::from_utc(const utc_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2079 {
|
|
ferencd@0
|
2080 using std::chrono::seconds;
|
|
ferencd@0
|
2081 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
2082 return tai_time<CD>{t.time_since_epoch()} +
|
|
ferencd@0
|
2083 (sys_days(year{1970}/January/1) - sys_days(year{1958}/January/1) + seconds{10});
|
|
ferencd@0
|
2084 }
|
|
ferencd@0
|
2085
|
|
ferencd@0
|
2086 inline
|
|
ferencd@0
|
2087 tai_clock::time_point
|
|
ferencd@0
|
2088 tai_clock::now()
|
|
ferencd@0
|
2089 {
|
|
ferencd@0
|
2090 return from_utc(utc_clock::now());
|
|
ferencd@0
|
2091 }
|
|
ferencd@0
|
2092
|
|
ferencd@0
|
2093 template <class Duration>
|
|
ferencd@0
|
2094 inline
|
|
ferencd@0
|
2095 local_time<typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2096 tai_clock::to_local(const tai_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2097 {
|
|
ferencd@0
|
2098 using CD = typename std::common_type<Duration, date::days>::type;
|
|
ferencd@0
|
2099 return local_time<CD>{t.time_since_epoch()} -
|
|
ferencd@0
|
2100 (local_days(year{1970}/January/1) - local_days(year{1958}/January/1));
|
|
ferencd@0
|
2101 }
|
|
ferencd@0
|
2102
|
|
ferencd@0
|
2103 template <class Duration>
|
|
ferencd@0
|
2104 inline
|
|
ferencd@0
|
2105 tai_time<typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2106 tai_clock::from_local(const local_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2107 {
|
|
ferencd@0
|
2108 using CD = typename std::common_type<Duration, date::days>::type;
|
|
ferencd@0
|
2109 return tai_time<CD>{t.time_since_epoch()} +
|
|
ferencd@0
|
2110 (local_days(year{1970}/January/1) - local_days(year{1958}/January/1));
|
|
ferencd@0
|
2111 }
|
|
ferencd@0
|
2112
|
|
ferencd@0
|
2113 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
2114 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
2115 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
ferencd@0
|
2116 const tai_time<Duration>& t)
|
|
ferencd@0
|
2117 {
|
|
ferencd@0
|
2118 const std::string abbrev("TAI");
|
|
ferencd@0
|
2119 CONSTDATA std::chrono::seconds offset{0};
|
|
ferencd@0
|
2120 return to_stream(os, fmt, tai_clock::to_local(t), &abbrev, &offset);
|
|
ferencd@0
|
2121 }
|
|
ferencd@0
|
2122
|
|
ferencd@0
|
2123 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
2124 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
2125 operator<<(std::basic_ostream<CharT, Traits>& os, const tai_time<Duration>& t)
|
|
ferencd@0
|
2126 {
|
|
ferencd@0
|
2127 const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}};
|
|
ferencd@0
|
2128 return to_stream(os, fmt, t);
|
|
ferencd@0
|
2129 }
|
|
ferencd@0
|
2130
|
|
ferencd@0
|
2131 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
ferencd@0
|
2132 std::basic_istream<CharT, Traits>&
|
|
ferencd@0
|
2133 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
ferencd@0
|
2134 tai_time<Duration>& tp,
|
|
ferencd@0
|
2135 std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
ferencd@0
|
2136 std::chrono::minutes* offset = nullptr)
|
|
ferencd@0
|
2137 {
|
|
ferencd@0
|
2138 local_time<Duration> lp;
|
|
ferencd@0
|
2139 from_stream(is, fmt, lp, abbrev, offset);
|
|
ferencd@0
|
2140 if (!is.fail())
|
|
ferencd@0
|
2141 tp = tai_clock::from_local(lp);
|
|
ferencd@0
|
2142 return is;
|
|
ferencd@0
|
2143 }
|
|
ferencd@0
|
2144
|
|
ferencd@0
|
2145 // gps_clock
|
|
ferencd@0
|
2146
|
|
ferencd@0
|
2147 class gps_clock
|
|
ferencd@0
|
2148 {
|
|
ferencd@0
|
2149 public:
|
|
ferencd@0
|
2150 using duration = std::chrono::system_clock::duration;
|
|
ferencd@0
|
2151 using rep = duration::rep;
|
|
ferencd@0
|
2152 using period = duration::period;
|
|
ferencd@0
|
2153 using time_point = std::chrono::time_point<gps_clock>;
|
|
ferencd@0
|
2154 static const bool is_steady = false;
|
|
ferencd@0
|
2155
|
|
ferencd@0
|
2156 static time_point now();
|
|
ferencd@0
|
2157
|
|
ferencd@0
|
2158 template<typename Duration>
|
|
ferencd@0
|
2159 static
|
|
ferencd@0
|
2160 std::chrono::time_point<utc_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2161 to_utc(const std::chrono::time_point<gps_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2162
|
|
ferencd@0
|
2163 template<typename Duration>
|
|
ferencd@0
|
2164 static
|
|
ferencd@0
|
2165 std::chrono::time_point<gps_clock, typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2166 from_utc(const std::chrono::time_point<utc_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2167
|
|
ferencd@0
|
2168 template<typename Duration>
|
|
ferencd@0
|
2169 static
|
|
ferencd@0
|
2170 std::chrono::time_point<local_t, typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2171 to_local(const std::chrono::time_point<gps_clock, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2172
|
|
ferencd@0
|
2173 template<typename Duration>
|
|
ferencd@0
|
2174 static
|
|
ferencd@0
|
2175 std::chrono::time_point<gps_clock, typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2176 from_local(const std::chrono::time_point<local_t, Duration>&) NOEXCEPT;
|
|
ferencd@0
|
2177 };
|
|
ferencd@0
|
2178
|
|
ferencd@0
|
2179 template <class Duration>
|
|
ferencd@0
|
2180 using gps_time = std::chrono::time_point<gps_clock, Duration>;
|
|
ferencd@0
|
2181
|
|
ferencd@0
|
2182 using gps_seconds = gps_time<std::chrono::seconds>;
|
|
ferencd@0
|
2183
|
|
ferencd@0
|
2184 template <class Duration>
|
|
ferencd@0
|
2185 inline
|
|
ferencd@0
|
2186 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2187 gps_clock::to_utc(const gps_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2188 {
|
|
ferencd@0
|
2189 using std::chrono::seconds;
|
|
ferencd@0
|
2190 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
2191 return utc_time<CD>{t.time_since_epoch()} +
|
|
ferencd@0
|
2192 (sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1) +
|
|
ferencd@0
|
2193 seconds{9});
|
|
ferencd@0
|
2194 }
|
|
ferencd@0
|
2195
|
|
ferencd@0
|
2196 template <class Duration>
|
|
ferencd@0
|
2197 inline
|
|
ferencd@0
|
2198 gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2199 gps_clock::from_utc(const utc_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2200 {
|
|
ferencd@0
|
2201 using std::chrono::seconds;
|
|
ferencd@0
|
2202 using CD = typename std::common_type<Duration, seconds>::type;
|
|
ferencd@0
|
2203 return gps_time<CD>{t.time_since_epoch()} -
|
|
ferencd@0
|
2204 (sys_days(year{1980}/January/Sunday[1]) - sys_days(year{1970}/January/1) +
|
|
ferencd@0
|
2205 seconds{9});
|
|
ferencd@0
|
2206 }
|
|
ferencd@0
|
2207
|
|
ferencd@0
|
2208 inline
|
|
ferencd@0
|
2209 gps_clock::time_point
|
|
ferencd@0
|
2210 gps_clock::now()
|
|
ferencd@0
|
2211 {
|
|
ferencd@0
|
2212 return from_utc(utc_clock::now());
|
|
ferencd@0
|
2213 }
|
|
ferencd@0
|
2214
|
|
ferencd@0
|
2215 template <class Duration>
|
|
ferencd@0
|
2216 inline
|
|
ferencd@0
|
2217 local_time<typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2218 gps_clock::to_local(const gps_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2219 {
|
|
ferencd@0
|
2220 using CD = typename std::common_type<Duration, date::days>::type;
|
|
ferencd@0
|
2221 return local_time<CD>{t.time_since_epoch()} +
|
|
ferencd@0
|
2222 (local_days(year{1980}/January/Sunday[1]) - local_days(year{1970}/January/1));
|
|
ferencd@0
|
2223 }
|
|
ferencd@0
|
2224
|
|
ferencd@0
|
2225 template <class Duration>
|
|
ferencd@0
|
2226 inline
|
|
ferencd@0
|
2227 gps_time<typename std::common_type<Duration, date::days>::type>
|
|
ferencd@0
|
2228 gps_clock::from_local(const local_time<Duration>& t) NOEXCEPT
|
|
ferencd@0
|
2229 {
|
|
ferencd@0
|
2230 using CD = typename std::common_type<Duration, date::days>::type;
|
|
ferencd@0
|
2231 return gps_time<CD>{t.time_since_epoch()} -
|
|
ferencd@0
|
2232 (local_days(year{1980}/January/Sunday[1]) - local_days(year{1970}/January/1));
|
|
ferencd@0
|
2233 }
|
|
ferencd@0
|
2234
|
|
ferencd@0
|
2235
|
|
ferencd@0
|
2236 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
2237 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
2238 to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|
ferencd@0
|
2239 const gps_time<Duration>& t)
|
|
ferencd@0
|
2240 {
|
|
ferencd@0
|
2241 const std::string abbrev("GPS");
|
|
ferencd@0
|
2242 CONSTDATA std::chrono::seconds offset{0};
|
|
ferencd@0
|
2243 return to_stream(os, fmt, gps_clock::to_local(t), &abbrev, &offset);
|
|
ferencd@0
|
2244 }
|
|
ferencd@0
|
2245
|
|
ferencd@0
|
2246 template <class CharT, class Traits, class Duration>
|
|
ferencd@0
|
2247 std::basic_ostream<CharT, Traits>&
|
|
ferencd@0
|
2248 operator<<(std::basic_ostream<CharT, Traits>& os, const gps_time<Duration>& t)
|
|
ferencd@0
|
2249 {
|
|
ferencd@0
|
2250 const CharT fmt[] = {'%', 'F', ' ', '%', 'T', CharT{}};
|
|
ferencd@0
|
2251 return to_stream(os, fmt, t);
|
|
ferencd@0
|
2252 }
|
|
ferencd@0
|
2253
|
|
ferencd@0
|
2254 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
|
|
ferencd@0
|
2255 std::basic_istream<CharT, Traits>&
|
|
ferencd@0
|
2256 from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|
ferencd@0
|
2257 gps_time<Duration>& tp,
|
|
ferencd@0
|
2258 std::basic_string<CharT, Traits, Alloc>* abbrev = nullptr,
|
|
ferencd@0
|
2259 std::chrono::minutes* offset = nullptr)
|
|
ferencd@0
|
2260 {
|
|
ferencd@0
|
2261 local_time<Duration> lp;
|
|
ferencd@0
|
2262 from_stream(is, fmt, lp, abbrev, offset);
|
|
ferencd@0
|
2263 if (!is.fail())
|
|
ferencd@0
|
2264 tp = gps_clock::from_local(lp);
|
|
ferencd@0
|
2265 return is;
|
|
ferencd@0
|
2266 }
|
|
ferencd@0
|
2267
|
|
ferencd@0
|
2268 // clock_time_conversion
|
|
ferencd@0
|
2269
|
|
ferencd@0
|
2270 template <class DstClock, class SrcClock>
|
|
ferencd@0
|
2271 struct clock_time_conversion
|
|
ferencd@0
|
2272 {};
|
|
ferencd@0
|
2273
|
|
ferencd@0
|
2274 template <>
|
|
ferencd@0
|
2275 struct clock_time_conversion<std::chrono::system_clock, std::chrono::system_clock>
|
|
ferencd@0
|
2276 {
|
|
ferencd@0
|
2277 template <class Duration>
|
|
ferencd@0
|
2278 sys_time<Duration>
|
|
ferencd@0
|
2279 operator()(const sys_time<Duration>& st) const
|
|
ferencd@0
|
2280 {
|
|
ferencd@0
|
2281 return st;
|
|
ferencd@0
|
2282 }
|
|
ferencd@0
|
2283 };
|
|
ferencd@0
|
2284
|
|
ferencd@0
|
2285 template <>
|
|
ferencd@0
|
2286 struct clock_time_conversion<utc_clock, utc_clock>
|
|
ferencd@0
|
2287 {
|
|
ferencd@0
|
2288 template <class Duration>
|
|
ferencd@0
|
2289 utc_time<Duration>
|
|
ferencd@0
|
2290 operator()(const utc_time<Duration>& ut) const
|
|
ferencd@0
|
2291 {
|
|
ferencd@0
|
2292 return ut;
|
|
ferencd@0
|
2293 }
|
|
ferencd@0
|
2294 };
|
|
ferencd@0
|
2295
|
|
ferencd@0
|
2296 template<>
|
|
ferencd@0
|
2297 struct clock_time_conversion<local_t, local_t>
|
|
ferencd@0
|
2298 {
|
|
ferencd@0
|
2299 template <class Duration>
|
|
ferencd@0
|
2300 local_time<Duration>
|
|
ferencd@0
|
2301 operator()(const local_time<Duration>& lt) const
|
|
ferencd@0
|
2302 {
|
|
ferencd@0
|
2303 return lt;
|
|
ferencd@0
|
2304 }
|
|
ferencd@0
|
2305 };
|
|
ferencd@0
|
2306
|
|
ferencd@0
|
2307 template <>
|
|
ferencd@0
|
2308 struct clock_time_conversion<utc_clock, std::chrono::system_clock>
|
|
ferencd@0
|
2309 {
|
|
ferencd@0
|
2310 template <class Duration>
|
|
ferencd@0
|
2311 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2312 operator()(const sys_time<Duration>& st) const
|
|
ferencd@0
|
2313 {
|
|
ferencd@0
|
2314 return utc_clock::from_sys(st);
|
|
ferencd@0
|
2315 }
|
|
ferencd@0
|
2316 };
|
|
ferencd@0
|
2317
|
|
ferencd@0
|
2318 template <>
|
|
ferencd@0
|
2319 struct clock_time_conversion<std::chrono::system_clock, utc_clock>
|
|
ferencd@0
|
2320 {
|
|
ferencd@0
|
2321 template <class Duration>
|
|
ferencd@0
|
2322 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2323 operator()(const utc_time<Duration>& ut) const
|
|
ferencd@0
|
2324 {
|
|
ferencd@0
|
2325 return utc_clock::to_sys(ut);
|
|
ferencd@0
|
2326 }
|
|
ferencd@0
|
2327 };
|
|
ferencd@0
|
2328
|
|
ferencd@0
|
2329 template<>
|
|
ferencd@0
|
2330 struct clock_time_conversion<local_t, std::chrono::system_clock>
|
|
ferencd@0
|
2331 {
|
|
ferencd@0
|
2332 template <class Duration>
|
|
ferencd@0
|
2333 local_time<Duration>
|
|
ferencd@0
|
2334 operator()(const sys_time<Duration>& st) const
|
|
ferencd@0
|
2335 {
|
|
ferencd@0
|
2336 return local_time<Duration>{st.time_since_epoch()};
|
|
ferencd@0
|
2337 }
|
|
ferencd@0
|
2338 };
|
|
ferencd@0
|
2339
|
|
ferencd@0
|
2340 template<>
|
|
ferencd@0
|
2341 struct clock_time_conversion<std::chrono::system_clock, local_t>
|
|
ferencd@0
|
2342 {
|
|
ferencd@0
|
2343 template <class Duration>
|
|
ferencd@0
|
2344 sys_time<Duration>
|
|
ferencd@0
|
2345 operator()(const local_time<Duration>& lt) const
|
|
ferencd@0
|
2346 {
|
|
ferencd@0
|
2347 return sys_time<Duration>{lt.time_since_epoch()};
|
|
ferencd@0
|
2348 }
|
|
ferencd@0
|
2349 };
|
|
ferencd@0
|
2350
|
|
ferencd@0
|
2351 template<>
|
|
ferencd@0
|
2352 struct clock_time_conversion<utc_clock, local_t>
|
|
ferencd@0
|
2353 {
|
|
ferencd@0
|
2354 template <class Duration>
|
|
ferencd@0
|
2355 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2356 operator()(const local_time<Duration>& lt) const
|
|
ferencd@0
|
2357 {
|
|
ferencd@0
|
2358 return utc_clock::from_local(lt);
|
|
ferencd@0
|
2359 }
|
|
ferencd@0
|
2360 };
|
|
ferencd@0
|
2361
|
|
ferencd@0
|
2362 template<>
|
|
ferencd@0
|
2363 struct clock_time_conversion<local_t, utc_clock>
|
|
ferencd@0
|
2364 {
|
|
ferencd@0
|
2365 template <class Duration>
|
|
ferencd@0
|
2366 local_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2367 operator()(const utc_time<Duration>& ut) const
|
|
ferencd@0
|
2368 {
|
|
ferencd@0
|
2369 return utc_clock::to_local(ut);
|
|
ferencd@0
|
2370 }
|
|
ferencd@0
|
2371 };
|
|
ferencd@0
|
2372
|
|
ferencd@0
|
2373 template<typename Clock>
|
|
ferencd@0
|
2374 struct clock_time_conversion<Clock, Clock>
|
|
ferencd@0
|
2375 {
|
|
ferencd@0
|
2376 template <class Duration>
|
|
ferencd@0
|
2377 std::chrono::time_point<Clock, Duration>
|
|
ferencd@0
|
2378 operator()(const std::chrono::time_point<Clock, Duration>& tp) const
|
|
ferencd@0
|
2379 {
|
|
ferencd@0
|
2380 return tp;
|
|
ferencd@0
|
2381 }
|
|
ferencd@0
|
2382 };
|
|
ferencd@0
|
2383
|
|
ferencd@0
|
2384 namespace ctc_detail
|
|
ferencd@0
|
2385 {
|
|
ferencd@0
|
2386
|
|
ferencd@0
|
2387 template <class Clock, class Duration>
|
|
ferencd@0
|
2388 using time_point = std::chrono::time_point<Clock, Duration>;
|
|
ferencd@0
|
2389
|
|
ferencd@0
|
2390 using std::declval;
|
|
ferencd@0
|
2391 using std::chrono::system_clock;
|
|
ferencd@0
|
2392
|
|
ferencd@0
|
2393 //Check if TimePoint is time for given clock,
|
|
ferencd@0
|
2394 //if not emits hard error
|
|
ferencd@0
|
2395 template <class Clock, class TimePoint>
|
|
ferencd@0
|
2396 struct return_clock_time
|
|
ferencd@0
|
2397 {
|
|
ferencd@0
|
2398 using clock_time_point = time_point<Clock, typename TimePoint::duration>;
|
|
ferencd@0
|
2399 using type = TimePoint;
|
|
ferencd@0
|
2400
|
|
ferencd@0
|
2401 static_assert(std::is_same<TimePoint, clock_time_point>::value,
|
|
ferencd@0
|
2402 "time point with appropariate clock shall be returned");
|
|
ferencd@0
|
2403 };
|
|
ferencd@0
|
2404
|
|
ferencd@0
|
2405 // Check if Clock has to_sys method accepting TimePoint with given duration const& and
|
|
ferencd@0
|
2406 // returning sys_time. If so has nested type member equal to return type to_sys.
|
|
ferencd@0
|
2407 template <class Clock, class Duration, class = void>
|
|
ferencd@0
|
2408 struct return_to_sys
|
|
ferencd@0
|
2409 {};
|
|
ferencd@0
|
2410
|
|
ferencd@0
|
2411 template <class Clock, class Duration>
|
|
ferencd@0
|
2412 struct return_to_sys
|
|
ferencd@0
|
2413 <
|
|
ferencd@0
|
2414 Clock, Duration,
|
|
ferencd@0
|
2415 decltype(Clock::to_sys(declval<time_point<Clock, Duration> const&>()), void())
|
|
ferencd@0
|
2416 >
|
|
ferencd@0
|
2417 : return_clock_time
|
|
ferencd@0
|
2418 <
|
|
ferencd@0
|
2419 system_clock,
|
|
ferencd@0
|
2420 decltype(Clock::to_sys(declval<time_point<Clock, Duration> const&>()))
|
|
ferencd@0
|
2421 >
|
|
ferencd@0
|
2422 {};
|
|
ferencd@0
|
2423
|
|
ferencd@0
|
2424 // Similiar to above
|
|
ferencd@0
|
2425 template <class Clock, class Duration, class = void>
|
|
ferencd@0
|
2426 struct return_from_sys
|
|
ferencd@0
|
2427 {};
|
|
ferencd@0
|
2428
|
|
ferencd@0
|
2429 template <class Clock, class Duration>
|
|
ferencd@0
|
2430 struct return_from_sys
|
|
ferencd@0
|
2431 <
|
|
ferencd@0
|
2432 Clock, Duration,
|
|
ferencd@0
|
2433 decltype(Clock::from_sys(declval<time_point<system_clock, Duration> const&>()),
|
|
ferencd@0
|
2434 void())
|
|
ferencd@0
|
2435 >
|
|
ferencd@0
|
2436 : return_clock_time
|
|
ferencd@0
|
2437 <
|
|
ferencd@0
|
2438 Clock,
|
|
ferencd@0
|
2439 decltype(Clock::from_sys(declval<time_point<system_clock, Duration> const&>()))
|
|
ferencd@0
|
2440 >
|
|
ferencd@0
|
2441 {};
|
|
ferencd@0
|
2442
|
|
ferencd@0
|
2443 // Similiar to above
|
|
ferencd@0
|
2444 template <class Clock, class Duration, class = void>
|
|
ferencd@0
|
2445 struct return_to_utc
|
|
ferencd@0
|
2446 {};
|
|
ferencd@0
|
2447
|
|
ferencd@0
|
2448 template <class Clock, class Duration>
|
|
ferencd@0
|
2449 struct return_to_utc
|
|
ferencd@0
|
2450 <
|
|
ferencd@0
|
2451 Clock, Duration,
|
|
ferencd@0
|
2452 decltype(Clock::to_utc(declval<time_point<Clock, Duration> const&>()), void())
|
|
ferencd@0
|
2453 >
|
|
ferencd@0
|
2454 : return_clock_time
|
|
ferencd@0
|
2455 <
|
|
ferencd@0
|
2456 utc_clock,
|
|
ferencd@0
|
2457 decltype(Clock::to_utc(declval<time_point<Clock, Duration> const&>()))>
|
|
ferencd@0
|
2458 {};
|
|
ferencd@0
|
2459
|
|
ferencd@0
|
2460 // Similiar to above
|
|
ferencd@0
|
2461 template <class Clock, class Duration, class = void>
|
|
ferencd@0
|
2462 struct return_from_utc
|
|
ferencd@0
|
2463 {};
|
|
ferencd@0
|
2464
|
|
ferencd@0
|
2465 template <class Clock, class Duration>
|
|
ferencd@0
|
2466 struct return_from_utc
|
|
ferencd@0
|
2467 <
|
|
ferencd@0
|
2468 Clock, Duration,
|
|
ferencd@0
|
2469 decltype(Clock::from_utc(declval<time_point<utc_clock, Duration> const&>()),
|
|
ferencd@0
|
2470 void())
|
|
ferencd@0
|
2471 >
|
|
ferencd@0
|
2472 : return_clock_time
|
|
ferencd@0
|
2473 <
|
|
ferencd@0
|
2474 Clock,
|
|
ferencd@0
|
2475 decltype(Clock::from_utc(declval<time_point<utc_clock, Duration> const&>()))
|
|
ferencd@0
|
2476 >
|
|
ferencd@0
|
2477 {};
|
|
ferencd@0
|
2478
|
|
ferencd@0
|
2479 // Similiar to above
|
|
ferencd@0
|
2480 template<typename Clock, typename Duration, typename = void>
|
|
ferencd@0
|
2481 struct return_to_local
|
|
ferencd@0
|
2482 {};
|
|
ferencd@0
|
2483
|
|
ferencd@0
|
2484 template<typename Clock, typename Duration>
|
|
ferencd@0
|
2485 struct return_to_local
|
|
ferencd@0
|
2486 <
|
|
ferencd@0
|
2487 Clock, Duration,
|
|
ferencd@0
|
2488 decltype(Clock::to_local(declval<time_point<Clock, Duration> const&>()),
|
|
ferencd@0
|
2489 void())
|
|
ferencd@0
|
2490 >
|
|
ferencd@0
|
2491 : return_clock_time
|
|
ferencd@0
|
2492 <
|
|
ferencd@0
|
2493 local_t,
|
|
ferencd@0
|
2494 decltype(Clock::to_local(declval<time_point<Clock, Duration> const&>()))
|
|
ferencd@0
|
2495 >
|
|
ferencd@0
|
2496 {};
|
|
ferencd@0
|
2497
|
|
ferencd@0
|
2498 // Similiar to above
|
|
ferencd@0
|
2499 template<typename Clock, typename Duration, typename = void>
|
|
ferencd@0
|
2500 struct return_from_local
|
|
ferencd@0
|
2501 {};
|
|
ferencd@0
|
2502
|
|
ferencd@0
|
2503 template<typename Clock, typename Duration>
|
|
ferencd@0
|
2504 struct return_from_local
|
|
ferencd@0
|
2505 <
|
|
ferencd@0
|
2506 Clock, Duration,
|
|
ferencd@0
|
2507 decltype(Clock::from_local(declval<time_point<local_t, Duration> const&>()),
|
|
ferencd@0
|
2508 void())
|
|
ferencd@0
|
2509 >
|
|
ferencd@0
|
2510 : return_clock_time
|
|
ferencd@0
|
2511 <
|
|
ferencd@0
|
2512 Clock,
|
|
ferencd@0
|
2513 decltype(Clock::from_local(declval<time_point<local_t, Duration> const&>()))
|
|
ferencd@0
|
2514 >
|
|
ferencd@0
|
2515 {};
|
|
ferencd@0
|
2516
|
|
ferencd@0
|
2517 } // namespace ctc_detail
|
|
ferencd@0
|
2518
|
|
ferencd@0
|
2519 template <class SrcClock>
|
|
ferencd@0
|
2520 struct clock_time_conversion<std::chrono::system_clock, SrcClock>
|
|
ferencd@0
|
2521 {
|
|
ferencd@0
|
2522 template <class Duration>
|
|
ferencd@0
|
2523 typename ctc_detail::return_to_sys<SrcClock, Duration>::type
|
|
ferencd@0
|
2524 operator()(const std::chrono::time_point<SrcClock, Duration>& tp) const
|
|
ferencd@0
|
2525 {
|
|
ferencd@0
|
2526 return SrcClock::to_sys(tp);
|
|
ferencd@0
|
2527 }
|
|
ferencd@0
|
2528 };
|
|
ferencd@0
|
2529
|
|
ferencd@0
|
2530 template <class DstClock>
|
|
ferencd@0
|
2531 struct clock_time_conversion<DstClock, std::chrono::system_clock>
|
|
ferencd@0
|
2532 {
|
|
ferencd@0
|
2533 template <class Duration>
|
|
ferencd@0
|
2534 typename ctc_detail::return_from_sys<DstClock, Duration>::type
|
|
ferencd@0
|
2535 operator()(const sys_time<Duration>& st) const
|
|
ferencd@0
|
2536 {
|
|
ferencd@0
|
2537 return DstClock::from_sys(st);
|
|
ferencd@0
|
2538 }
|
|
ferencd@0
|
2539 };
|
|
ferencd@0
|
2540
|
|
ferencd@0
|
2541 template <class SrcClock>
|
|
ferencd@0
|
2542 struct clock_time_conversion<utc_clock, SrcClock>
|
|
ferencd@0
|
2543 {
|
|
ferencd@0
|
2544 template <class Duration>
|
|
ferencd@0
|
2545 typename ctc_detail::return_to_utc<SrcClock, Duration>::type
|
|
ferencd@0
|
2546 operator()(const std::chrono::time_point<SrcClock, Duration>& tp) const
|
|
ferencd@0
|
2547 {
|
|
ferencd@0
|
2548 return SrcClock::to_utc(tp);
|
|
ferencd@0
|
2549 }
|
|
ferencd@0
|
2550 };
|
|
ferencd@0
|
2551
|
|
ferencd@0
|
2552 template <class DstClock>
|
|
ferencd@0
|
2553 struct clock_time_conversion<DstClock, utc_clock>
|
|
ferencd@0
|
2554 {
|
|
ferencd@0
|
2555 template <class Duration>
|
|
ferencd@0
|
2556 typename ctc_detail::return_from_utc<DstClock, Duration>::type
|
|
ferencd@0
|
2557 operator()(const utc_time<Duration>& ut) const
|
|
ferencd@0
|
2558 {
|
|
ferencd@0
|
2559 return DstClock::from_utc(ut);
|
|
ferencd@0
|
2560 }
|
|
ferencd@0
|
2561 };
|
|
ferencd@0
|
2562
|
|
ferencd@0
|
2563 template<typename SrcClock>
|
|
ferencd@0
|
2564 struct clock_time_conversion<local_t, SrcClock>
|
|
ferencd@0
|
2565 {
|
|
ferencd@0
|
2566 template <class Duration>
|
|
ferencd@0
|
2567 typename ctc_detail::return_to_local<SrcClock, Duration>::type
|
|
ferencd@0
|
2568 operator()(const std::chrono::time_point<SrcClock, Duration>& tp) const
|
|
ferencd@0
|
2569 {
|
|
ferencd@0
|
2570 return SrcClock::to_local(tp);
|
|
ferencd@0
|
2571 }
|
|
ferencd@0
|
2572 };
|
|
ferencd@0
|
2573
|
|
ferencd@0
|
2574 template<typename DstClock>
|
|
ferencd@0
|
2575 struct clock_time_conversion<DstClock, local_t>
|
|
ferencd@0
|
2576 {
|
|
ferencd@0
|
2577 template <class Duration>
|
|
ferencd@0
|
2578 typename ctc_detail::return_from_local<DstClock, Duration>::type
|
|
ferencd@0
|
2579 operator()(const local_time<Duration>& lt) const
|
|
ferencd@0
|
2580 {
|
|
ferencd@0
|
2581 return DstClock::from_local(lt);
|
|
ferencd@0
|
2582 }
|
|
ferencd@0
|
2583 };
|
|
ferencd@0
|
2584
|
|
ferencd@0
|
2585 namespace clock_cast_detail
|
|
ferencd@0
|
2586 {
|
|
ferencd@0
|
2587
|
|
ferencd@0
|
2588 template <class Clock, class Duration>
|
|
ferencd@0
|
2589 using time_point = std::chrono::time_point<Clock, Duration>;
|
|
ferencd@0
|
2590 using std::chrono::system_clock;
|
|
ferencd@0
|
2591
|
|
ferencd@0
|
2592 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2593 auto
|
|
ferencd@0
|
2594 conv_clock(const time_point<SrcClock, Duration>& t)
|
|
ferencd@0
|
2595 -> decltype(std::declval<clock_time_conversion<DstClock, SrcClock>>()(t))
|
|
ferencd@0
|
2596 {
|
|
ferencd@0
|
2597 return clock_time_conversion<DstClock, SrcClock>{}(t);
|
|
ferencd@0
|
2598 }
|
|
ferencd@0
|
2599
|
|
ferencd@0
|
2600 //direct trait conversion, 1st candidate
|
|
ferencd@0
|
2601 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2602 auto
|
|
ferencd@0
|
2603 cc_impl(const time_point<SrcClock, Duration>& t, const time_point<SrcClock, Duration>*)
|
|
ferencd@0
|
2604 -> decltype(conv_clock<DstClock>(t))
|
|
ferencd@0
|
2605 {
|
|
ferencd@0
|
2606 return conv_clock<DstClock>(t);
|
|
ferencd@0
|
2607 }
|
|
ferencd@0
|
2608
|
|
ferencd@0
|
2609 //conversion through sys, 2nd candidate
|
|
ferencd@0
|
2610 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2611 auto
|
|
ferencd@0
|
2612 cc_impl(const time_point<SrcClock, Duration>& t, const void*)
|
|
ferencd@0
|
2613 -> decltype(conv_clock<DstClock>(conv_clock<system_clock>(t)))
|
|
ferencd@0
|
2614 {
|
|
ferencd@0
|
2615 return conv_clock<DstClock>(conv_clock<system_clock>(t));
|
|
ferencd@0
|
2616 }
|
|
ferencd@0
|
2617
|
|
ferencd@0
|
2618 //conversion through utc, 2nd candidate
|
|
ferencd@0
|
2619 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2620 auto
|
|
ferencd@0
|
2621 cc_impl(const time_point<SrcClock, Duration>& t, const void*)
|
|
ferencd@0
|
2622 -> decltype(0, // MSVC_WORKAROUND
|
|
ferencd@0
|
2623 conv_clock<DstClock>(conv_clock<utc_clock>(t)))
|
|
ferencd@0
|
2624 {
|
|
ferencd@0
|
2625 return conv_clock<DstClock>(conv_clock<utc_clock>(t));
|
|
ferencd@0
|
2626 }
|
|
ferencd@0
|
2627
|
|
ferencd@0
|
2628 //conversion through sys and utc, 3rd candidate
|
|
ferencd@0
|
2629 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2630 auto
|
|
ferencd@0
|
2631 cc_impl(const time_point<SrcClock, Duration>& t, ...)
|
|
ferencd@0
|
2632 -> decltype(conv_clock<DstClock>(conv_clock<utc_clock>(conv_clock<system_clock>(t))))
|
|
ferencd@0
|
2633 {
|
|
ferencd@0
|
2634 return conv_clock<DstClock>(conv_clock<utc_clock>(conv_clock<system_clock>(t)));
|
|
ferencd@0
|
2635 }
|
|
ferencd@0
|
2636
|
|
ferencd@0
|
2637 //conversion through utc and sys, 3rd candidate
|
|
ferencd@0
|
2638 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2639 auto
|
|
ferencd@0
|
2640 cc_impl(const time_point<SrcClock, Duration>& t, ...)
|
|
ferencd@0
|
2641 -> decltype(0, // MSVC_WORKAROUND
|
|
ferencd@0
|
2642 conv_clock<DstClock>(conv_clock<system_clock>(conv_clock<utc_clock>(t))))
|
|
ferencd@0
|
2643 {
|
|
ferencd@0
|
2644 return conv_clock<DstClock>(conv_clock<system_clock>(conv_clock<utc_clock>(t)));
|
|
ferencd@0
|
2645 }
|
|
ferencd@0
|
2646
|
|
ferencd@0
|
2647 } // namespace clock_cast_detail
|
|
ferencd@0
|
2648
|
|
ferencd@0
|
2649 template <class DstClock, class SrcClock, class Duration>
|
|
ferencd@0
|
2650 auto
|
|
ferencd@0
|
2651 clock_cast(const std::chrono::time_point<SrcClock, Duration>& tp)
|
|
ferencd@0
|
2652 -> decltype(clock_cast_detail::cc_impl<DstClock>(tp, &tp))
|
|
ferencd@0
|
2653 {
|
|
ferencd@0
|
2654 return clock_cast_detail::cc_impl<DstClock>(tp, &tp);
|
|
ferencd@0
|
2655 }
|
|
ferencd@0
|
2656
|
|
ferencd@0
|
2657 // Deprecated API
|
|
ferencd@0
|
2658
|
|
ferencd@0
|
2659 template <class Duration>
|
|
ferencd@0
|
2660 inline
|
|
ferencd@0
|
2661 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2662 to_sys_time(const utc_time<Duration>& t)
|
|
ferencd@0
|
2663 {
|
|
ferencd@0
|
2664 return utc_clock::to_sys(t);
|
|
ferencd@0
|
2665 }
|
|
ferencd@0
|
2666
|
|
ferencd@0
|
2667 template <class Duration>
|
|
ferencd@0
|
2668 inline
|
|
ferencd@0
|
2669 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2670 to_sys_time(const tai_time<Duration>& t)
|
|
ferencd@0
|
2671 {
|
|
ferencd@0
|
2672 return utc_clock::to_sys(tai_clock::to_utc(t));
|
|
ferencd@0
|
2673 }
|
|
ferencd@0
|
2674
|
|
ferencd@0
|
2675 template <class Duration>
|
|
ferencd@0
|
2676 inline
|
|
ferencd@0
|
2677 sys_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2678 to_sys_time(const gps_time<Duration>& t)
|
|
ferencd@0
|
2679 {
|
|
ferencd@0
|
2680 return utc_clock::to_sys(gps_clock::to_utc(t));
|
|
ferencd@0
|
2681 }
|
|
ferencd@0
|
2682
|
|
ferencd@0
|
2683
|
|
ferencd@0
|
2684 template <class Duration>
|
|
ferencd@0
|
2685 inline
|
|
ferencd@0
|
2686 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2687 to_utc_time(const sys_time<Duration>& t)
|
|
ferencd@0
|
2688 {
|
|
ferencd@0
|
2689 return utc_clock::from_sys(t);
|
|
ferencd@0
|
2690 }
|
|
ferencd@0
|
2691
|
|
ferencd@0
|
2692 template <class Duration>
|
|
ferencd@0
|
2693 inline
|
|
ferencd@0
|
2694 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2695 to_utc_time(const tai_time<Duration>& t)
|
|
ferencd@0
|
2696 {
|
|
ferencd@0
|
2697 return tai_clock::to_utc(t);
|
|
ferencd@0
|
2698 }
|
|
ferencd@0
|
2699
|
|
ferencd@0
|
2700 template <class Duration>
|
|
ferencd@0
|
2701 inline
|
|
ferencd@0
|
2702 utc_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2703 to_utc_time(const gps_time<Duration>& t)
|
|
ferencd@0
|
2704 {
|
|
ferencd@0
|
2705 return gps_clock::to_utc(t);
|
|
ferencd@0
|
2706 }
|
|
ferencd@0
|
2707
|
|
ferencd@0
|
2708
|
|
ferencd@0
|
2709 template <class Duration>
|
|
ferencd@0
|
2710 inline
|
|
ferencd@0
|
2711 tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2712 to_tai_time(const sys_time<Duration>& t)
|
|
ferencd@0
|
2713 {
|
|
ferencd@0
|
2714 return tai_clock::from_utc(utc_clock::from_sys(t));
|
|
ferencd@0
|
2715 }
|
|
ferencd@0
|
2716
|
|
ferencd@0
|
2717 template <class Duration>
|
|
ferencd@0
|
2718 inline
|
|
ferencd@0
|
2719 tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2720 to_tai_time(const utc_time<Duration>& t)
|
|
ferencd@0
|
2721 {
|
|
ferencd@0
|
2722 return tai_clock::from_utc(t);
|
|
ferencd@0
|
2723 }
|
|
ferencd@0
|
2724
|
|
ferencd@0
|
2725 template <class Duration>
|
|
ferencd@0
|
2726 inline
|
|
ferencd@0
|
2727 tai_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2728 to_tai_time(const gps_time<Duration>& t)
|
|
ferencd@0
|
2729 {
|
|
ferencd@0
|
2730 return tai_clock::from_utc(gps_clock::to_utc(t));
|
|
ferencd@0
|
2731 }
|
|
ferencd@0
|
2732
|
|
ferencd@0
|
2733
|
|
ferencd@0
|
2734 template <class Duration>
|
|
ferencd@0
|
2735 inline
|
|
ferencd@0
|
2736 gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2737 to_gps_time(const sys_time<Duration>& t)
|
|
ferencd@0
|
2738 {
|
|
ferencd@0
|
2739 return gps_clock::from_utc(utc_clock::from_sys(t));
|
|
ferencd@0
|
2740 }
|
|
ferencd@0
|
2741
|
|
ferencd@0
|
2742 template <class Duration>
|
|
ferencd@0
|
2743 inline
|
|
ferencd@0
|
2744 gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2745 to_gps_time(const utc_time<Duration>& t)
|
|
ferencd@0
|
2746 {
|
|
ferencd@0
|
2747 return gps_clock::from_utc(t);
|
|
ferencd@0
|
2748 }
|
|
ferencd@0
|
2749
|
|
ferencd@0
|
2750 template <class Duration>
|
|
ferencd@0
|
2751 inline
|
|
ferencd@0
|
2752 gps_time<typename std::common_type<Duration, std::chrono::seconds>::type>
|
|
ferencd@0
|
2753 to_gps_time(const tai_time<Duration>& t)
|
|
ferencd@0
|
2754 {
|
|
ferencd@0
|
2755 return gps_clock::from_utc(tai_clock::to_utc(t));
|
|
ferencd@0
|
2756 }
|
|
ferencd@0
|
2757
|
|
ferencd@0
|
2758 #endif // !MISSING_LEAP_SECONDS
|
|
ferencd@0
|
2759
|
|
ferencd@0
|
2760 } // namespace date
|
|
ferencd@0
|
2761
|
|
ferencd@0
|
2762 #endif // TZ_H
|