summaryrefslogtreecommitdiff
path: root/absl/time/internal/cctz/src/time_zone_info.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/time/internal/cctz/src/time_zone_info.h')
-rw-r--r--absl/time/internal/cctz/src/time_zone_info.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/absl/time/internal/cctz/src/time_zone_info.h b/absl/time/internal/cctz/src/time_zone_info.h
new file mode 100644
index 00000000..b4d1696b
--- /dev/null
+++ b/absl/time/internal/cctz/src/time_zone_info.h
@@ -0,0 +1,132 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
+#define ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_
+
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "absl/time/internal/cctz/include/cctz/civil_time.h"
+#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+#include "absl/time/internal/cctz/include/cctz/zone_info_source.h"
+#include "time_zone_if.h"
+#include "tzfile.h"
+
+namespace absl {
+namespace time_internal {
+namespace cctz {
+
+// A transition to a new UTC offset.
+struct Transition {
+ std::int_least64_t unix_time; // the instant of this transition
+ std::uint_least8_t type_index; // index of the transition type
+ civil_second civil_sec; // local civil time of transition
+ civil_second prev_civil_sec; // local civil time one second earlier
+
+ struct ByUnixTime {
+ inline bool operator()(const Transition& lhs, const Transition& rhs) const {
+ return lhs.unix_time < rhs.unix_time;
+ }
+ };
+ struct ByCivilTime {
+ inline bool operator()(const Transition& lhs, const Transition& rhs) const {
+ return lhs.civil_sec < rhs.civil_sec;
+ }
+ };
+};
+
+// The characteristics of a particular transition.
+struct TransitionType {
+ std::int_least32_t utc_offset; // the new prevailing UTC offset
+ civil_second civil_max; // max convertible civil time for offset
+ civil_second civil_min; // min convertible civil time for offset
+ bool is_dst; // did we move into daylight-saving time
+ std::uint_least8_t abbr_index; // index of the new abbreviation
+};
+
+// A time zone backed by the IANA Time Zone Database (zoneinfo).
+class TimeZoneInfo : public TimeZoneIf {
+ public:
+ TimeZoneInfo() = default;
+ TimeZoneInfo(const TimeZoneInfo&) = delete;
+ TimeZoneInfo& operator=(const TimeZoneInfo&) = delete;
+
+ // Loads the zoneinfo for the given name, returning true if successful.
+ bool Load(const std::string& name);
+
+ // TimeZoneIf implementations.
+ time_zone::absolute_lookup BreakTime(
+ const time_point<sys_seconds>& tp) const override;
+ time_zone::civil_lookup MakeTime(
+ const civil_second& cs) const override;
+ std::string Description() const override;
+ bool NextTransition(time_point<sys_seconds>* tp) const override;
+ bool PrevTransition(time_point<sys_seconds>* tp) const override;
+
+ private:
+ struct Header { // counts of:
+ std::size_t timecnt; // transition times
+ std::size_t typecnt; // transition types
+ std::size_t charcnt; // zone abbreviation characters
+ std::size_t leapcnt; // leap seconds (we expect none)
+ std::size_t ttisstdcnt; // UTC/local indicators (unused)
+ std::size_t ttisgmtcnt; // standard/wall indicators (unused)
+
+ bool Build(const tzhead& tzh);
+ std::size_t DataLength(std::size_t time_len) const;
+ };
+
+ void CheckTransition(const std::string& name, const TransitionType& tt,
+ std::int_fast32_t offset, bool is_dst,
+ const std::string& abbr) const;
+ bool EquivTransitions(std::uint_fast8_t tt1_index,
+ std::uint_fast8_t tt2_index) const;
+ void ExtendTransitions(const std::string& name, const Header& hdr);
+
+ bool ResetToBuiltinUTC(const sys_seconds& offset);
+ bool Load(const std::string& name, ZoneInfoSource* zip);
+
+ // Helpers for BreakTime() and MakeTime().
+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
+ const TransitionType& tt) const;
+ time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
+ const Transition& tr) const;
+ time_zone::civil_lookup TimeLocal(const civil_second& cs,
+ year_t c4_shift) const;
+
+ std::vector<Transition> transitions_; // ordered by unix_time and civil_sec
+ std::vector<TransitionType> transition_types_; // distinct transition types
+ std::uint_fast8_t default_transition_type_; // for before first transition
+ std::string abbreviations_; // all the NUL-terminated abbreviations
+
+ std::string future_spec_; // for after the last zic transition
+ bool extended_; // future_spec_ was used to generate transitions
+ year_t last_year_; // the final year of the generated transitions
+
+ // We remember the transitions found during the last BreakTime() and
+ // MakeTime() calls. If the next request is for the same transition we
+ // will avoid re-searching.
+ mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint
+ mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint
+};
+
+} // namespace cctz
+} // namespace time_internal
+} // namespace absl
+
+#endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_