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