2018-04-23 17:17:58 +02:00
|
|
|
// 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(
|
2018-06-21 21:55:12 +02:00
|
|
|
const time_point<seconds>& tp) const override;
|
2018-04-23 17:17:58 +02:00
|
|
|
time_zone::civil_lookup MakeTime(
|
|
|
|
const civil_second& cs) const override;
|
2018-06-29 23:00:35 +02:00
|
|
|
bool NextTransition(const time_point<seconds>& tp,
|
|
|
|
time_zone::civil_transition* trans) const override;
|
|
|
|
bool PrevTransition(const time_point<seconds>& tp,
|
|
|
|
time_zone::civil_transition* trans) const override;
|
|
|
|
std::string Version() const override;
|
2018-04-23 17:17:58 +02:00
|
|
|
std::string Description() 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);
|
|
|
|
|
2018-06-21 21:55:12 +02:00
|
|
|
bool ResetToBuiltinUTC(const seconds& offset);
|
2018-04-23 17:17:58 +02:00
|
|
|
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
|
|
|
|
|
2018-06-29 23:00:35 +02:00
|
|
|
std::string version_; // the tzdata version if available
|
2018-04-23 17:17:58 +02:00
|
|
|
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_
|