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 ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ 16 #define ABSL_TIME_INTERNAL_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 "absl/base/config.h" 26 #include "absl/time/internal/cctz/include/cctz/civil_time.h" 27 #include "absl/time/internal/cctz/include/cctz/time_zone.h" 28 #include "absl/time/internal/cctz/include/cctz/zone_info_source.h" 29 #include "time_zone_if.h" 30 #include "tzfile.h" 31 32 namespace absl { 33 ABSL_NAMESPACE_BEGIN 34 namespace time_internal { 35 namespace cctz { 36 37 // A transition to a new UTC offset. 38 struct Transition { 39 std::int_least64_t unix_time; // the instant of this transition 40 std::uint_least8_t type_index; // index of the transition type 41 civil_second civil_sec; // local civil time of transition 42 civil_second prev_civil_sec; // local civil time one second earlier 43 44 struct ByUnixTime { operatorTransition::ByUnixTime45 inline bool operator()(const Transition& lhs, const Transition& rhs) const { 46 return lhs.unix_time < rhs.unix_time; 47 } 48 }; 49 struct ByCivilTime { operatorTransition::ByCivilTime50 inline bool operator()(const Transition& lhs, const Transition& rhs) const { 51 return lhs.civil_sec < rhs.civil_sec; 52 } 53 }; 54 }; 55 56 // The characteristics of a particular transition. 57 struct TransitionType { 58 std::int_least32_t utc_offset; // the new prevailing UTC offset 59 civil_second civil_max; // max convertible civil time for offset 60 civil_second civil_min; // min convertible civil time for offset 61 bool is_dst; // did we move into daylight-saving time 62 std::uint_least8_t abbr_index; // index of the new abbreviation 63 }; 64 65 // A time zone backed by the IANA Time Zone Database (zoneinfo). 66 class TimeZoneInfo : public TimeZoneIf { 67 public: 68 // Factories. 69 static std::unique_ptr<TimeZoneInfo> UTC(); // never fails 70 static std::unique_ptr<TimeZoneInfo> Make(const std::string& name); 71 72 // TimeZoneIf implementations. 73 time_zone::absolute_lookup BreakTime( 74 const time_point<seconds>& tp) const override; 75 time_zone::civil_lookup MakeTime(const civil_second& cs) const override; 76 bool NextTransition(const time_point<seconds>& tp, 77 time_zone::civil_transition* trans) const override; 78 bool PrevTransition(const time_point<seconds>& tp, 79 time_zone::civil_transition* trans) const override; 80 std::string Version() const override; 81 std::string Description() const override; 82 83 private: 84 TimeZoneInfo() = default; 85 TimeZoneInfo(const TimeZoneInfo&) = delete; 86 TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; 87 88 bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, 89 const std::string& abbr, std::uint_least8_t* index); 90 bool EquivTransitions(std::uint_fast8_t tt1_index, 91 std::uint_fast8_t tt2_index) const; 92 bool ExtendTransitions(); 93 94 bool ResetToBuiltinUTC(const seconds& offset); 95 bool Load(const std::string& name); 96 bool Load(ZoneInfoSource* zip); 97 98 // Helpers for BreakTime() and MakeTime(). 99 time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, 100 const TransitionType& tt) const; 101 time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, 102 const Transition& tr) const; 103 time_zone::civil_lookup TimeLocal(const civil_second& cs, 104 year_t c4_shift) const; 105 106 std::vector<Transition> transitions_; // ordered by unix_time and civil_sec 107 std::vector<TransitionType> transition_types_; // distinct transition types 108 std::uint_fast8_t default_transition_type_; // for before first transition 109 std::string abbreviations_; // all the NUL-terminated abbreviations 110 111 std::string version_; // the tzdata version if available 112 std::string future_spec_; // for after the last zic transition 113 bool extended_; // future_spec_ was used to generate transitions 114 year_t last_year_; // the final year of the generated transitions 115 116 // We remember the transitions found during the last BreakTime() and 117 // MakeTime() calls. If the next request is for the same transition we 118 // will avoid re-searching. 119 mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint 120 mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint 121 }; 122 123 } // namespace cctz 124 } // namespace time_internal 125 ABSL_NAMESPACE_END 126 } // namespace absl 127 128 #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ 129