Commit 2119e40e by Abseil Team Committed by Copybara-Service

Roll forward of CCTZ update; fixed by clang release.

PiperOrigin-RevId: 544146637
Change-Id: I5ca44465f451956ae246081ce826891599b18b9c
parent bba65bd1
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <ratio> // NOLINT: We use std::ratio in this header
#include <string> #include <string>
#include <utility> #include <utility>
......
...@@ -14,15 +14,13 @@ ...@@ -14,15 +14,13 @@
#if !defined(HAS_STRPTIME) #if !defined(HAS_STRPTIME)
#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__VXWORKS__) #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__VXWORKS__)
#define HAS_STRPTIME \ #define HAS_STRPTIME 1 // Assume everyone else has strptime().
1 // assume everyone has strptime() except windows
// and VxWorks
#endif #endif
#endif #endif
#if defined(HAS_STRPTIME) && HAS_STRPTIME #if defined(HAS_STRPTIME) && HAS_STRPTIME
#if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) #if !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__)
#define _XOPEN_SOURCE // Definedness suffices for strptime. #define _XOPEN_SOURCE // Definedness suffices for strptime().
#endif #endif
#endif #endif
......
...@@ -23,19 +23,19 @@ ABSL_NAMESPACE_BEGIN ...@@ -23,19 +23,19 @@ ABSL_NAMESPACE_BEGIN
namespace time_internal { namespace time_internal {
namespace cctz { namespace cctz {
std::unique_ptr<TimeZoneIf> TimeZoneIf::Load(const std::string& name) { std::unique_ptr<TimeZoneIf> TimeZoneIf::UTC() { return TimeZoneInfo::UTC(); }
std::unique_ptr<TimeZoneIf> TimeZoneIf::Make(const std::string& name) {
// Support "libc:localtime" and "libc:*" to access the legacy // Support "libc:localtime" and "libc:*" to access the legacy
// localtime and UTC support respectively from the C library. // localtime and UTC support respectively from the C library.
// NOTE: The "libc:*" zones are internal, test-only interfaces, and // NOTE: The "libc:*" zones are internal, test-only interfaces, and
// are subject to change/removal without notice. Do not use them. // are subject to change/removal without notice. Do not use them.
if (name.compare(0, 5, "libc:") == 0) { if (name.compare(0, 5, "libc:") == 0) {
return std::unique_ptr<TimeZoneIf>(new TimeZoneLibC(name.substr(5))); return TimeZoneLibC::Make(name.substr(5));
} }
// Otherwise use the "zoneinfo" implementation by default. // Otherwise use the "zoneinfo" implementation.
std::unique_ptr<TimeZoneInfo> tz(new TimeZoneInfo); return TimeZoneInfo::Make(name);
if (!tz->Load(name)) tz.reset();
return std::unique_ptr<TimeZoneIf>(tz.release());
} }
// Defined out-of-line to avoid emitting a weak vtable in all TUs. // Defined out-of-line to avoid emitting a weak vtable in all TUs.
......
...@@ -33,8 +33,9 @@ namespace cctz { ...@@ -33,8 +33,9 @@ namespace cctz {
// Subclasses implement the functions for civil-time conversions in the zone. // Subclasses implement the functions for civil-time conversions in the zone.
class TimeZoneIf { class TimeZoneIf {
public: public:
// A factory function for TimeZoneIf implementations. // Factory functions for TimeZoneIf implementations.
static std::unique_ptr<TimeZoneIf> Load(const std::string& name); static std::unique_ptr<TimeZoneIf> UTC(); // never fails
static std::unique_ptr<TimeZoneIf> Make(const std::string& name);
virtual ~TimeZoneIf(); virtual ~TimeZoneIf();
...@@ -51,7 +52,9 @@ class TimeZoneIf { ...@@ -51,7 +52,9 @@ class TimeZoneIf {
virtual std::string Description() const = 0; virtual std::string Description() const = 0;
protected: protected:
TimeZoneIf() {} TimeZoneIf() = default;
TimeZoneIf(const TimeZoneIf&) = delete;
TimeZoneIf& operator=(const TimeZoneIf&) = delete;
}; };
// Convert between time_point<seconds> and a count of seconds since the // Convert between time_point<seconds> and a count of seconds since the
......
...@@ -99,11 +99,13 @@ void time_zone::Impl::ClearTimeZoneMapTestOnly() { ...@@ -99,11 +99,13 @@ void time_zone::Impl::ClearTimeZoneMapTestOnly() {
} }
} }
time_zone::Impl::Impl() : name_("UTC"), zone_(TimeZoneIf::UTC()) {}
time_zone::Impl::Impl(const std::string& name) time_zone::Impl::Impl(const std::string& name)
: name_(name), zone_(TimeZoneIf::Load(name_)) {} : name_(name), zone_(TimeZoneIf::Make(name_)) {}
const time_zone::Impl* time_zone::Impl::UTCImpl() { const time_zone::Impl* time_zone::Impl::UTCImpl() {
static const Impl* utc_impl = new Impl("UTC"); // never fails static const Impl* utc_impl = new Impl;
return utc_impl; return utc_impl;
} }
......
...@@ -78,7 +78,11 @@ class time_zone::Impl { ...@@ -78,7 +78,11 @@ class time_zone::Impl {
std::string Description() const { return zone_->Description(); } std::string Description() const { return zone_->Description(); }
private: private:
Impl();
explicit Impl(const std::string& name); explicit Impl(const std::string& name);
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
static const Impl* UTCImpl(); static const Impl* UTCImpl();
const std::string name_; const std::string name_;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <atomic> #include <atomic>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -64,12 +65,9 @@ struct TransitionType { ...@@ -64,12 +65,9 @@ struct TransitionType {
// A time zone backed by the IANA Time Zone Database (zoneinfo). // A time zone backed by the IANA Time Zone Database (zoneinfo).
class TimeZoneInfo : public TimeZoneIf { class TimeZoneInfo : public TimeZoneIf {
public: public:
TimeZoneInfo() = default; // Factories.
TimeZoneInfo(const TimeZoneInfo&) = delete; static std::unique_ptr<TimeZoneInfo> UTC(); // never fails
TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; static std::unique_ptr<TimeZoneInfo> Make(const std::string& name);
// Loads the zoneinfo for the given name, returning true if successful.
bool Load(const std::string& name);
// TimeZoneIf implementations. // TimeZoneIf implementations.
time_zone::absolute_lookup BreakTime( time_zone::absolute_lookup BreakTime(
...@@ -83,17 +81,9 @@ class TimeZoneInfo : public TimeZoneIf { ...@@ -83,17 +81,9 @@ class TimeZoneInfo : public TimeZoneIf {
std::string Description() const override; std::string Description() const override;
private: private:
struct Header { // counts of: TimeZoneInfo() = default;
std::size_t timecnt; // transition times TimeZoneInfo(const TimeZoneInfo&) = delete;
std::size_t typecnt; // transition types TimeZoneInfo& operator=(const TimeZoneInfo&) = delete;
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 ttisutcnt; // standard/wall indicators (unused)
bool Build(const tzhead& tzh);
std::size_t DataLength(std::size_t time_len) const;
};
bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
const std::string& abbr, std::uint_least8_t* index); const std::string& abbr, std::uint_least8_t* index);
...@@ -102,6 +92,7 @@ class TimeZoneInfo : public TimeZoneIf { ...@@ -102,6 +92,7 @@ class TimeZoneInfo : public TimeZoneIf {
bool ExtendTransitions(); bool ExtendTransitions();
bool ResetToBuiltinUTC(const seconds& offset); bool ResetToBuiltinUTC(const seconds& offset);
bool Load(const std::string& name);
bool Load(ZoneInfoSource* zip); bool Load(ZoneInfoSource* zip);
// Helpers for BreakTime() and MakeTime(). // Helpers for BreakTime() and MakeTime().
......
...@@ -62,7 +62,7 @@ auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) { ...@@ -62,7 +62,7 @@ auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
} }
#elif defined(__native_client__) || defined(__myriad2__) || \ #elif defined(__native_client__) || defined(__myriad2__) || \
defined(__EMSCRIPTEN__) defined(__EMSCRIPTEN__)
// Uses the globals: 'timezone' and 'tzname'. // Uses the globals: '_timezone' and 'tzname'.
auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) { auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) {
const bool is_dst = tm.tm_isdst > 0; const bool is_dst = tm.tm_isdst > 0;
return _timezone + (is_dst ? 60 * 60 : 0); return _timezone + (is_dst ? 60 * 60 : 0);
...@@ -193,8 +193,9 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, tm_gmtoff_t offset) { ...@@ -193,8 +193,9 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, tm_gmtoff_t offset) {
} // namespace } // namespace
TimeZoneLibC::TimeZoneLibC(const std::string& name) std::unique_ptr<TimeZoneLibC> TimeZoneLibC::Make(const std::string& name) {
: local_(name == "localtime") {} return std::unique_ptr<TimeZoneLibC>(new TimeZoneLibC(name));
}
time_zone::absolute_lookup TimeZoneLibC::BreakTime( time_zone::absolute_lookup TimeZoneLibC::BreakTime(
const time_point<seconds>& tp) const { const time_point<seconds>& tp) const {
...@@ -323,6 +324,9 @@ std::string TimeZoneLibC::Description() const { ...@@ -323,6 +324,9 @@ std::string TimeZoneLibC::Description() const {
return local_ ? "localtime" : "UTC"; return local_ ? "localtime" : "UTC";
} }
TimeZoneLibC::TimeZoneLibC(const std::string& name)
: local_(name == "localtime") {}
} // namespace cctz } // namespace cctz
} // namespace time_internal } // namespace time_internal
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
......
...@@ -27,10 +27,10 @@ namespace cctz { ...@@ -27,10 +27,10 @@ namespace cctz {
// A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3), // A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3),
// and which therefore only supports UTC and the local time zone. // and which therefore only supports UTC and the local time zone.
// TODO: Add support for fixed offsets from UTC.
class TimeZoneLibC : public TimeZoneIf { class TimeZoneLibC : public TimeZoneIf {
public: public:
explicit TimeZoneLibC(const std::string& name); // Factory.
static std::unique_ptr<TimeZoneLibC> Make(const std::string& name);
// TimeZoneIf implementations. // TimeZoneIf implementations.
time_zone::absolute_lookup BreakTime( time_zone::absolute_lookup BreakTime(
...@@ -44,6 +44,10 @@ class TimeZoneLibC : public TimeZoneIf { ...@@ -44,6 +44,10 @@ class TimeZoneLibC : public TimeZoneIf {
std::string Description() const override; std::string Description() const override;
private: private:
explicit TimeZoneLibC(const std::string& name);
TimeZoneLibC(const TimeZoneLibC&) = delete;
TimeZoneLibC& operator=(const TimeZoneLibC&) = delete;
const bool local_; // localtime or UTC const bool local_; // localtime or UTC
}; };
......
...@@ -734,6 +734,10 @@ TEST(TimeZone, UTC) { ...@@ -734,6 +734,10 @@ TEST(TimeZone, UTC) {
time_zone loaded_utc0; time_zone loaded_utc0;
EXPECT_TRUE(load_time_zone("UTC0", &loaded_utc0)); EXPECT_TRUE(load_time_zone("UTC0", &loaded_utc0));
EXPECT_EQ(loaded_utc0, utc); EXPECT_EQ(loaded_utc0, utc);
time_zone loaded_bad;
EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &loaded_bad));
EXPECT_EQ(loaded_bad, utc);
} }
TEST(TimeZone, NamedTimeZones) { TEST(TimeZone, NamedTimeZones) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment