/src/cctz/src/time_zone_info.h
Line | Count | Source |
1 | | // Copyright 2016 Google Inc. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef CCTZ_TIME_ZONE_INFO_H_ |
16 | | #define CCTZ_TIME_ZONE_INFO_H_ |
17 | | |
18 | | #include <atomic> |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | #include <memory> |
22 | | #include <string> |
23 | | #include <vector> |
24 | | |
25 | | #include "cctz/civil_time.h" |
26 | | #include "cctz/time_zone.h" |
27 | | #include "cctz/zone_info_source.h" |
28 | | #include "time_zone_if.h" |
29 | | #include "tzfile.h" |
30 | | |
31 | | namespace cctz { |
32 | | |
33 | | // A transition to a new UTC offset. |
34 | | struct Transition { |
35 | | std::int_least64_t unix_time; // the instant of this transition |
36 | | std::uint_least8_t type_index; // index of the transition type |
37 | | civil_second civil_sec; // local civil time of transition |
38 | | civil_second prev_civil_sec; // local civil time one second earlier |
39 | | |
40 | | struct ByUnixTime { |
41 | 40.9k | inline bool operator()(const Transition& lhs, const Transition& rhs) const { |
42 | 40.9k | return lhs.unix_time < rhs.unix_time; |
43 | 40.9k | } |
44 | | }; |
45 | | struct ByCivilTime { |
46 | 239k | inline bool operator()(const Transition& lhs, const Transition& rhs) const { |
47 | 239k | return lhs.civil_sec < rhs.civil_sec; |
48 | 239k | } |
49 | | }; |
50 | | }; |
51 | | |
52 | | // The characteristics of a particular transition. |
53 | | struct TransitionType { |
54 | | std::int_least32_t utc_offset; // the new prevailing UTC offset |
55 | | civil_second civil_max; // max convertible civil time for offset |
56 | | civil_second civil_min; // min convertible civil time for offset |
57 | | bool is_dst; // did we move into daylight-saving time |
58 | | std::uint_least8_t abbr_index; // index of the new abbreviation |
59 | | }; |
60 | | |
61 | | // A time zone backed by the IANA Time Zone Database (zoneinfo). |
62 | | class TimeZoneInfo : public TimeZoneIf { |
63 | | public: |
64 | | // Factories. |
65 | | static std::unique_ptr<TimeZoneInfo> UTC(); // never fails |
66 | | static std::unique_ptr<TimeZoneInfo> Make(const std::string& name); |
67 | | |
68 | | // TimeZoneIf implementations. |
69 | | time_zone::absolute_lookup BreakTime( |
70 | | const time_point<seconds>& tp) const override; |
71 | | time_zone::civil_lookup MakeTime( |
72 | | const civil_second& cs) const override; |
73 | | bool NextTransition(const time_point<seconds>& tp, |
74 | | time_zone::civil_transition* trans) const override; |
75 | | bool PrevTransition(const time_point<seconds>& tp, |
76 | | time_zone::civil_transition* trans) const override; |
77 | | std::string Version() const override; |
78 | | std::string Description() const override; |
79 | | |
80 | | private: |
81 | 1.22k | TimeZoneInfo() = default; |
82 | | TimeZoneInfo(const TimeZoneInfo&) = delete; |
83 | | TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; |
84 | | |
85 | | bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, |
86 | | const std::string& abbr, std::uint_least8_t* index); |
87 | | bool EquivTransitions(std::uint_fast8_t tt1_index, |
88 | | std::uint_fast8_t tt2_index) const; |
89 | | bool ExtendTransitions(); |
90 | | |
91 | | bool ResetToBuiltinUTC(const seconds& offset); |
92 | | bool Load(const std::string& name); |
93 | | bool Load(ZoneInfoSource* zip); |
94 | | |
95 | | // Helpers for BreakTime() and MakeTime(). |
96 | | time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, |
97 | | const TransitionType& tt) const; |
98 | | time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, |
99 | | const Transition& tr) const; |
100 | | time_zone::civil_lookup TimeLocal(const civil_second& cs, |
101 | | year_t c4_shift) const; |
102 | | |
103 | | std::vector<Transition> transitions_; // ordered by unix_time and civil_sec |
104 | | std::vector<TransitionType> transition_types_; // distinct transition types |
105 | | std::uint_fast8_t default_transition_type_; // for before first transition |
106 | | std::string abbreviations_; // all the NUL-terminated abbreviations |
107 | | |
108 | | std::string version_; // the tzdata version if available |
109 | | std::string future_spec_; // for after the last zic transition |
110 | | bool extended_; // future_spec_ was used to generate transitions |
111 | | year_t last_year_; // the final year of the generated transitions |
112 | | |
113 | | // We remember the transitions found during the last BreakTime() and |
114 | | // MakeTime() calls. If the next request is for the same transition we |
115 | | // will avoid re-searching. |
116 | | mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint |
117 | | mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint |
118 | | }; |
119 | | |
120 | | } // namespace cctz |
121 | | |
122 | | #endif // CCTZ_TIME_ZONE_INFO_H_ |