diff options
author | Pirate Praveen <praveen@debian.org> | 2023-03-06 20:25:41 +0530 |
---|---|---|
committer | Pirate Praveen <praveen@debian.org> | 2023-03-06 20:25:41 +0530 |
commit | 079dd8737bbaaaeeca3a95c2b858a62d8a620d5a (patch) | |
tree | 6af54966e17bcfe48ecdb0b5cdf43cc953d5358c /absl/time/internal/cctz | |
parent | 2bbc47f307f1e24f3f44a108d571bffa5a3faa63 (diff) | |
parent | f5afcb784c9b1c501c1144b7aab84555881ca871 (diff) |
Merge tag '20220623.1-1' into bullseye-backports-staging
Diffstat (limited to 'absl/time/internal/cctz')
65 files changed, 424 insertions, 91 deletions
diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index 45a95292..7304d40d 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") - package(features = ["-parse_headers"]) licenses(["notice"]) @@ -26,14 +24,14 @@ filegroup( config_setting( name = "osx", constraint_values = [ - "@bazel_tools//platforms:osx", + "@platforms//os:osx", ], ) config_setting( name = "ios", constraint_values = [ - "@bazel_tools//platforms:ios", + "@platforms//os:ios", ], ) @@ -87,7 +85,11 @@ cc_library( deps = [ ":civil_time", "//absl/base:config", - ], + ] + select( + { + "//conditions:default": [], + }, + ), ) ### tests @@ -117,6 +119,7 @@ cc_test( "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time", @@ -136,6 +139,7 @@ cc_test( "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time", diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index 8aadde57..a5b084e6 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -84,14 +84,13 @@ CONSTEXPR_F bool is_leap_year(year_t y) noexcept { return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); } CONSTEXPR_F int year_index(year_t y, month_t m) noexcept { - return (static_cast<int>((y + (m > 2)) % 400) + 400) % 400; + const int yi = static_cast<int>((y + (m > 2)) % 400); + return yi < 0 ? yi + 400 : yi; } -CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept { - const int yi = year_index(y, m); +CONSTEXPR_F int days_per_century(int yi) noexcept { return 36524 + (yi == 0 || yi > 300); } -CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept { - const int yi = year_index(y, m); +CONSTEXPR_F int days_per_4years(int yi) noexcept { return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96); } CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept { @@ -133,17 +132,22 @@ CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh, } } if (d > 365) { + int yi = year_index(ey, m); // Index into Gregorian 400 year cycle. for (;;) { - int n = days_per_century(ey, m); + int n = days_per_century(yi); if (d <= n) break; d -= n; ey += 100; + yi += 100; + if (yi >= 400) yi -= 400; } for (;;) { - int n = days_per_4years(ey, m); + int n = days_per_4years(yi); if (d <= n) break; d -= n; ey += 4; + yi += 4; + if (yi >= 400) yi -= 400; } for (;;) { int n = days_per_year(ey, m); diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h index 5562a37b..6e382dc6 100644 --- a/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/absl/time/internal/cctz/include/cctz/time_zone.h @@ -22,6 +22,7 @@ #include <chrono> #include <cstdint> +#include <limits> #include <string> #include <utility> @@ -41,20 +42,9 @@ using sys_seconds = seconds; // Deprecated. Use cctz::seconds instead. namespace detail { template <typename D> -inline std::pair<time_point<seconds>, D> split_seconds( - const time_point<D>& tp) { - auto sec = std::chrono::time_point_cast<seconds>(tp); - auto sub = tp - sec; - if (sub.count() < 0) { - sec -= seconds(1); - sub += seconds(1); - } - return {sec, std::chrono::duration_cast<D>(sub)}; -} -inline std::pair<time_point<seconds>, seconds> split_seconds( - const time_point<seconds>& tp) { - return {tp, seconds::zero()}; -} +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp); +std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp); } // namespace detail // cctz::time_zone is an opaque, small, value-type class representing a @@ -279,6 +269,20 @@ std::string format(const std::string&, const time_point<seconds>&, const femtoseconds&, const time_zone&); bool parse(const std::string&, const std::string&, const time_zone&, time_point<seconds>*, femtoseconds*, std::string* err = nullptr); +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp); +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp); +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp); +bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp); } // namespace detail // Formats the given time_point in the given cctz::time_zone according to @@ -369,15 +373,84 @@ inline bool parse(const std::string& fmt, const std::string& input, const time_zone& tz, time_point<D>* tpp) { time_point<seconds> sec; detail::femtoseconds fs; - const bool b = detail::parse(fmt, input, tz, &sec, &fs); - if (b) { - // TODO: Return false if unrepresentable as a time_point<D>. - *tpp = std::chrono::time_point_cast<D>(sec); - *tpp += std::chrono::duration_cast<D>(fs); + return detail::parse(fmt, input, tz, &sec, &fs) && + detail::join_seconds(sec, fs, tpp); +} + +namespace detail { + +// Split a time_point<D> into a time_point<seconds> and a D subseconds. +// Undefined behavior if time_point<seconds> is not of sufficient range. +// Note that this means it is UB to call cctz::time_zone::lookup(tp) or +// cctz::format(fmt, tp, tz) with a time_point that is outside the range +// of a 64-bit std::time_t. +template <typename D> +std::pair<time_point<seconds>, D> split_seconds(const time_point<D>& tp) { + auto sec = std::chrono::time_point_cast<seconds>(tp); + auto sub = tp - sec; + if (sub.count() < 0) { + sec -= seconds(1); + sub += seconds(1); } - return b; + return {sec, std::chrono::duration_cast<D>(sub)}; +} + +inline std::pair<time_point<seconds>, seconds> split_seconds( + const time_point<seconds>& tp) { + return {tp, seconds::zero()}; } +// Join a time_point<seconds> and femto subseconds into a time_point<D>. +// Floors to the resolution of time_point<D>. Returns false if time_point<D> +// is not of sufficient range. +template <typename Rep, std::intmax_t Denom> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds& fs, + time_point<std::chrono::duration<Rep, std::ratio<1, Denom>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, Denom>>; + // TODO(#199): Return false if result unrepresentable as a time_point<D>. + *tpp = std::chrono::time_point_cast<D>(sec); + *tpp += std::chrono::duration_cast<D>(fs); + return true; +} + +template <typename Rep, std::intmax_t Num> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<Num, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<Num, 1>>; + auto count = sec.time_since_epoch().count(); + if (count >= 0 || count % Num == 0) { + count /= Num; + } else { + count /= Num; + count -= 1; + } + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +template <typename Rep> +bool join_seconds( + const time_point<seconds>& sec, const femtoseconds&, + time_point<std::chrono::duration<Rep, std::ratio<1, 1>>>* tpp) { + using D = std::chrono::duration<Rep, std::ratio<1, 1>>; + auto count = sec.time_since_epoch().count(); + if (count > (std::numeric_limits<Rep>::max)()) return false; + if (count < (std::numeric_limits<Rep>::min)()) return false; + *tpp = time_point<D>() + D{static_cast<Rep>(count)}; + return true; +} + +inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, + time_point<seconds>* tpp) { + *tpp = sec; + return true; +} + +} // namespace detail } // namespace cctz } // namespace time_internal ABSL_NAMESPACE_END diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc index 4e39188f..6770ad6b 100644 --- a/absl/time/internal/cctz/src/cctz_benchmark.cc +++ b/absl/time/internal/cctz/src/cctz_benchmark.cc @@ -648,6 +648,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Johnston", + "Pacific/Kanton", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc index 303c0244..f2b3294e 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -53,7 +53,7 @@ int Parse02d(const char* p) { } // namespace bool FixedOffsetFromName(const std::string& name, seconds* offset) { - if (name.compare(0, std::string::npos, "UTC", 3) == 0) { + if (name == "UTC" || name == "UTC0") { *offset = seconds::zero(); return true; } diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index a11f93e2..f1f79a20 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -13,15 +13,20 @@ // limitations under the License. #include <chrono> +#include <cstdint> #include <iomanip> #include <sstream> #include <string> +#include "absl/base/config.h" +#include "absl/time/internal/cctz/include/cctz/time_zone.h" +#if defined(__linux__) +#include <features.h> +#endif + #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" -#include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace chrono = std::chrono; @@ -182,8 +187,10 @@ TEST(Format, PosixConversions) { TestFormatSpecifier(tp, tz, "%F", "1970-01-01"); TestFormatSpecifier(tp, tz, "%g", "70"); TestFormatSpecifier(tp, tz, "%G", "1970"); +#if defined(__GLIBC__) TestFormatSpecifier(tp, tz, "%k", " 0"); TestFormatSpecifier(tp, tz, "%l", "12"); +#endif TestFormatSpecifier(tp, tz, "%n", "\n"); TestFormatSpecifier(tp, tz, "%R", "00:00"); TestFormatSpecifier(tp, tz, "%t", "\t"); @@ -215,7 +222,9 @@ TEST(Format, LocaleSpecific) { #if defined(__linux__) // SU/C99/TZ extensions TestFormatSpecifier(tp, tz, "%h", "Jan"); // Same as %b +#if defined(__GLIBC__) TestFormatSpecifier(tp, tz, "%P", "am"); +#endif TestFormatSpecifier(tp, tz, "%r", "12:00:00 AM"); // Modified conversion specifiers %E_ @@ -1044,9 +1053,11 @@ TEST(Parse, LocaleSpecific) { EXPECT_TRUE(parse("%h", "Feb", tz, &tp)); EXPECT_EQ(2, convert(tp, tz).month()); // Equivalent to %b +#if defined(__GLIBC__) tp = reset; EXPECT_TRUE(parse("%l %p", "5 PM", tz, &tp)); EXPECT_EQ(17, convert(tp, tz).hour()); +#endif tp = reset; EXPECT_TRUE(parse("%r", "03:44:55 PM", tz, &tp)); @@ -1054,6 +1065,7 @@ TEST(Parse, LocaleSpecific) { EXPECT_EQ(44, convert(tp, tz).minute()); EXPECT_EQ(55, convert(tp, tz).second()); +#if defined(__GLIBC__) tp = reset; EXPECT_TRUE(parse("%Ec", "Tue Nov 19 05:06:07 2013", tz, &tp)); EXPECT_EQ(convert(civil_second(2013, 11, 19, 5, 6, 7), tz), tp); @@ -1125,6 +1137,7 @@ TEST(Parse, LocaleSpecific) { EXPECT_TRUE(parse("%Oy", "04", tz, &tp)); EXPECT_EQ(2004, convert(tp, tz).year()); #endif +#endif } TEST(Parse, ExtendedSeconds) { @@ -1135,7 +1148,7 @@ TEST(Parse, ExtendedSeconds) { // All %E<prec>S cases are treated the same as %E*S on input. auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; - for (const std::string& prec : precisions) { + for (const std::string prec : precisions) { const std::string fmt = "%E" + prec + "S"; SCOPED_TRACE(fmt); time_point<chrono::nanoseconds> tp = unix_epoch; @@ -1217,7 +1230,7 @@ TEST(Parse, ExtendedSubeconds) { // All %E<prec>f cases are treated the same as %E*f on input. auto precisions = {"*", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; - for (const std::string& prec : precisions) { + for (const std::string prec : precisions) { const std::string fmt = "%E" + prec + "f"; SCOPED_TRACE(fmt); time_point<chrono::nanoseconds> tp = unix_epoch - chrono::seconds(1); @@ -1504,7 +1517,7 @@ TEST(Parse, MaxRange) { parse(RFC3339_sec, "292277026596-12-04T14:30:07-01:00", utc, &tp)); EXPECT_EQ(tp, time_point<absl::time_internal::cctz::seconds>::max()); EXPECT_FALSE( - parse(RFC3339_sec, "292277026596-12-04T15:30:07-01:00", utc, &tp)); + parse(RFC3339_sec, "292277026596-12-04T14:30:08-01:00", utc, &tp)); // tests the lower limit using +00:00 offset EXPECT_TRUE( @@ -1525,10 +1538,82 @@ TEST(Parse, MaxRange) { parse(RFC3339_sec, "9223372036854775807-12-31T23:59:59-00:01", utc, &tp)); EXPECT_FALSE(parse(RFC3339_sec, "-9223372036854775808-01-01T00:00:00+00:01", utc, &tp)); +} + +TEST(Parse, TimePointOverflow) { + const time_zone utc = utc_time_zone(); + + using D = chrono::duration<std::int64_t, std::nano>; + time_point<D> tp; + + EXPECT_TRUE( + parse(RFC3339_full, "2262-04-11T23:47:16.8547758079+00:00", utc, &tp)); + EXPECT_EQ(tp, time_point<D>::max()); + EXPECT_EQ("2262-04-11T23:47:16.854775807+00:00", + format(RFC3339_full, tp, utc)); +#if 0 + // TODO(#199): Will fail until cctz::parse() properly detects overflow. + EXPECT_FALSE( + parse(RFC3339_full, "2262-04-11T23:47:16.8547758080+00:00", utc, &tp)); + EXPECT_TRUE( + parse(RFC3339_full, "1677-09-21T00:12:43.1452241920+00:00", utc, &tp)); + EXPECT_EQ(tp, time_point<D>::min()); + EXPECT_EQ("1677-09-21T00:12:43.145224192+00:00", + format(RFC3339_full, tp, utc)); + EXPECT_FALSE( + parse(RFC3339_full, "1677-09-21T00:12:43.1452241919+00:00", utc, &tp)); +#endif + + using DS = chrono::duration<std::int8_t, chrono::seconds::period>; + time_point<DS> stp; + + EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T00:02:07.9+00:00", utc, &stp)); + EXPECT_EQ(stp, time_point<DS>::max()); + EXPECT_EQ("1970-01-01T00:02:07+00:00", format(RFC3339_full, stp, utc)); + EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T00:02:08+00:00", utc, &stp)); + + EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T23:57:52+00:00", utc, &stp)); + EXPECT_EQ(stp, time_point<DS>::min()); + EXPECT_EQ("1969-12-31T23:57:52+00:00", format(RFC3339_full, stp, utc)); + EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T23:57:51.9+00:00", utc, &stp)); + + using DM = chrono::duration<std::int8_t, chrono::minutes::period>; + time_point<DM> mtp; + + EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T02:07:59+00:00", utc, &mtp)); + EXPECT_EQ(mtp, time_point<DM>::max()); + EXPECT_EQ("1970-01-01T02:07:00+00:00", format(RFC3339_full, mtp, utc)); + EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T02:08:00+00:00", utc, &mtp)); + + EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T21:52:00+00:00", utc, &mtp)); + EXPECT_EQ(mtp, time_point<DM>::min()); + EXPECT_EQ("1969-12-31T21:52:00+00:00", format(RFC3339_full, mtp, utc)); + EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T21:51:59+00:00", utc, &mtp)); +} - // TODO: Add tests that parsing times with fractional seconds overflow - // appropriately. This can't be done until cctz::parse() properly detects - // overflow when combining the chrono seconds and femto. +TEST(Parse, TimePointOverflowFloor) { + const time_zone utc = utc_time_zone(); + + using D = chrono::duration<std::int64_t, std::micro>; + time_point<D> tp; + + EXPECT_TRUE( + parse(RFC3339_full, "294247-01-10T04:00:54.7758079+00:00", utc, &tp)); + EXPECT_EQ(tp, time_point<D>::max()); + EXPECT_EQ("294247-01-10T04:00:54.775807+00:00", + format(RFC3339_full, tp, utc)); +#if 0 + // TODO(#199): Will fail until cctz::parse() properly detects overflow. + EXPECT_FALSE( + parse(RFC3339_full, "294247-01-10T04:00:54.7758080+00:00", utc, &tp)); + EXPECT_TRUE( + parse(RFC3339_full, "-290308-12-21T19:59:05.2241920+00:00", utc, &tp)); + EXPECT_EQ(tp, time_point<D>::min()); + EXPECT_EQ("-290308-12-21T19:59:05.224192+00:00", + format(RFC3339_full, tp, utc)); + EXPECT_FALSE( + parse(RFC3339_full, "-290308-12-21T19:59:05.2241919+00:00", utc, &tp)); +#endif } // diff --git a/absl/time/internal/cctz/src/time_zone_if.h b/absl/time/internal/cctz/src/time_zone_if.h index 32c0891c..7d3e42d3 100644 --- a/absl/time/internal/cctz/src/time_zone_if.h +++ b/absl/time/internal/cctz/src/time_zone_if.h @@ -56,7 +56,8 @@ class TimeZoneIf { // Convert between time_point<seconds> and a count of seconds since the // Unix epoch. We assume that the std::chrono::system_clock and the -// Unix clock are second aligned, but not that they share an epoch. +// Unix clock are second aligned, and that the results are representable. +// (That is, that they share an epoch, which is required since C++20.) inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { return (tp - std::chrono::time_point_cast<seconds>( std::chrono::system_clock::from_time_t(0))) diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc index 8039353e..4f175d95 100644 --- a/absl/time/internal/cctz/src/time_zone_info.cc +++ b/absl/time/internal/cctz/src/time_zone_info.cc @@ -39,10 +39,12 @@ #include <cstdio> #include <cstdlib> #include <cstring> +#include <fstream> #include <functional> #include <memory> #include <sstream> #include <string> +#include <utility> #include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" @@ -576,14 +578,17 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { namespace { +using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>; + // fopen(3) adaptor. -inline FILE* FOpen(const char* path, const char* mode) { +inline FilePtr FOpen(const char* path, const char* mode) { #if defined(_MSC_VER) FILE* fp; if (fopen_s(&fp, path, mode) != 0) fp = nullptr; - return fp; + return FilePtr(fp, fclose); #else - return fopen(path, mode); // TODO: Enable the close-on-exec flag. + // TODO: Enable the close-on-exec flag. + return FilePtr(fopen(path, mode), fclose); #endif } @@ -611,11 +616,11 @@ class FileZoneInfoSource : public ZoneInfoSource { protected: explicit FileZoneInfoSource( - FILE* fp, std::size_t len = std::numeric_limits<std::size_t>::max()) - : fp_(fp, fclose), len_(len) {} + FilePtr fp, std::size_t len = std::numeric_limits<std::size_t>::max()) + : fp_(std::move(fp)), len_(len) {} private: - std::unique_ptr<FILE, int (*)(FILE*)> fp_; + FilePtr fp_; std::size_t len_; }; @@ -644,17 +649,9 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open( path.append(name, pos, std::string::npos); // Open the zoneinfo file. - FILE* fp = FOpen(path.c_str(), "rb"); + auto fp = FOpen(path.c_str(), "rb"); if (fp == nullptr) return nullptr; - std::size_t length = 0; - if (fseek(fp, 0, SEEK_END) == 0) { - long offset = ftell(fp); - if (offset >= 0) { - length = static_cast<std::size_t>(offset); - } - rewind(fp); - } - return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(fp, length)); + return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp))); } class AndroidZoneInfoSource : public FileZoneInfoSource { @@ -663,8 +660,9 @@ class AndroidZoneInfoSource : public FileZoneInfoSource { std::string Version() const override { return version_; } private: - explicit AndroidZoneInfoSource(FILE* fp, std::size_t len, const char* vers) - : FileZoneInfoSource(fp, len), version_(vers) {} + explicit AndroidZoneInfoSource(FilePtr fp, std::size_t len, + std::string version) + : FileZoneInfoSource(std::move(fp), len), version_(std::move(version)) {} std::string version_; }; @@ -676,8 +674,8 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( // See Android's libc/tzcode/bionic.cpp for additional information. for (const char* tzdata : {"/data/misc/zoneinfo/current/tzdata", "/system/usr/share/zoneinfo/tzdata"}) { - std::unique_ptr<FILE, int (*)(FILE*)> fp(FOpen(tzdata, "rb"), fclose); - if (fp.get() == nullptr) continue; + auto fp = FOpen(tzdata, "rb"); + if (fp == nullptr) continue; char hbuf[24]; // covers header.zonetab_offset too if (fread(hbuf, 1, sizeof(hbuf), fp.get()) != sizeof(hbuf)) continue; @@ -703,7 +701,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( if (strcmp(name.c_str() + pos, ebuf) == 0) { if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break; return std::unique_ptr<ZoneInfoSource>(new AndroidZoneInfoSource( - fp.release(), static_cast<std::size_t>(length), vers)); + std::move(fp), static_cast<std::size_t>(length), vers)); } } } @@ -711,6 +709,69 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open( return nullptr; } +// A zoneinfo source for use inside Fuchsia components. This attempts to +// read zoneinfo files from one of several known paths in a component's +// incoming namespace. [Config data][1] is preferred, but package-specific +// resources are also supported. +// +// Fuchsia's implementation supports `FileZoneInfoSource::Version()`. +// +// [1]: +// https://fuchsia.dev/fuchsia-src/development/components/data#using_config_data_in_your_component +class FuchsiaZoneInfoSource : public FileZoneInfoSource { + public: + static std::unique_ptr<ZoneInfoSource> Open(const std::string& name); + std::string Version() const override { return version_; } + + private: + explicit FuchsiaZoneInfoSource(FilePtr fp, std::string version) + : FileZoneInfoSource(std::move(fp)), version_(std::move(version)) {} + std::string version_; +}; + +std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open( + const std::string& name) { + // Use of the "file:" prefix is intended for testing purposes only. + const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0; + + // Prefixes where a Fuchsia component might find zoneinfo files, + // in descending order of preference. + const auto kTzdataPrefixes = { + "/config/data/tzdata/", + "/pkg/data/tzdata/", + "/data/tzdata/", + }; + const auto kEmptyPrefix = {""}; + const bool name_absolute = (pos != name.size() && name[pos] == '/'); + const auto prefixes = name_absolute ? kEmptyPrefix : kTzdataPrefixes; + + // Fuchsia builds place zoneinfo files at "<prefix><format><name>". + for (const std::string prefix : prefixes) { + std::string path = prefix; + if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format + path.append(name, pos, std::string::npos); + + auto fp = FOpen(path.c_str(), "rb"); + if (fp == nullptr) continue; + + std::string version; + if (!prefix.empty()) { + // Fuchsia builds place the version in "<prefix>revision.txt". + std::ifstream version_stream(prefix + "revision.txt"); + if (version_stream.is_open()) { + // revision.txt should contain no newlines, but to be + // defensive we read just the first line. + std::getline(version_stream, version); + } + } + + return std::unique_ptr<ZoneInfoSource>( + new FuchsiaZoneInfoSource(std::move(fp), std::move(version))); + } + + return nullptr; +} + } // namespace bool TimeZoneInfo::Load(const std::string& name) { @@ -728,6 +789,7 @@ bool TimeZoneInfo::Load(const std::string& name) { name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { if (auto z = FileZoneInfoSource::Open(n)) return z; if (auto z = AndroidZoneInfoSource::Open(n)) return z; + if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; return nullptr; }); return zip != nullptr && Load(zip.get()); diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc index efdea64b..898d04c1 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup.cc @@ -28,6 +28,13 @@ #include <vector> #endif +#if defined(__Fuchsia__) +#include <fuchsia/intl/cpp/fidl.h> +#include <lib/async-loop/cpp/loop.h> +#include <lib/sys/cpp/component_context.h> +#include <zircon/types.h> +#endif + #include <cstdlib> #include <cstring> #include <string> @@ -140,6 +147,48 @@ time_zone local_time_zone() { } CFRelease(tz_default); #endif +#if defined(__Fuchsia__) + std::string primary_tz; + [&]() { + // Note: We can't use the synchronous FIDL API here because it doesn't + // allow timeouts; if the FIDL call failed, local_time_zone() would never + // return. + + const zx::duration kTimeout = zx::msec(500); + + // Don't attach to the thread because otherwise the thread's dispatcher + // would be set to null when the loop is destroyed, causing any other FIDL + // code running on the same thread to crash. + async::Loop loop(&kAsyncLoopConfigNeverAttachToThread); + std::unique_ptr<sys::ComponentContext> context = + sys::ComponentContext::Create(); + + fuchsia::intl::PropertyProviderHandle handle; + zx_status_t status = context->svc()->Connect(handle.NewRequest()); + if (status != ZX_OK) { + return; + } + + fuchsia::intl::PropertyProviderPtr intl_provider; + status = intl_provider.Bind(std::move(handle), loop.dispatcher()); + if (status != ZX_OK) { + return; + } + + intl_provider->GetProfile( + [&loop, &primary_tz](fuchsia::intl::Profile profile) { + if (!profile.time_zones().empty()) { + primary_tz = profile.time_zones()[0].id; + } + loop.Quit(); + }); + loop.Run(zx::deadline_after(kTimeout)); + }(); + + if (!primary_tz.empty()) { + zone = primary_tz.c_str(); + } +#endif // Allow ${TZ} to override to default zone. char* tz_env = nullptr; diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index 9a1a8d6e..27a53c5c 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -21,10 +21,14 @@ #include <thread> #include <vector> -#include "gtest/gtest.h" #include "absl/base/config.h" -#include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" +#if defined(__linux__) +#include <features.h> +#endif + +#include "gtest/gtest.h" +#include "absl/time/internal/cctz/include/cctz/civil_time.h" namespace chrono = std::chrono; @@ -579,6 +583,7 @@ const char* const kTimeZoneNames[] = {"Africa/Abidjan", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Johnston", + "Pacific/Kanton", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", @@ -717,6 +722,18 @@ TEST(TimeZones, LoadZonesConcurrently) { } #endif +TEST(TimeZone, UTC) { + const time_zone utc = utc_time_zone(); + + time_zone loaded_utc; + EXPECT_TRUE(load_time_zone("UTC", &loaded_utc)); + EXPECT_EQ(loaded_utc, utc); + + time_zone loaded_utc0; + EXPECT_TRUE(load_time_zone("UTC0", &loaded_utc0)); + EXPECT_EQ(loaded_utc0, utc); +} + TEST(TimeZone, NamedTimeZones) { const time_zone utc = utc_time_zone(); EXPECT_EQ("UTC", utc.name()); @@ -1014,8 +1031,12 @@ TEST(MakeTime, SysSecondsLimits) { #endif const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900; tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), cut); +#if defined(__Fuchsia__) + // Fuchsia's gmtime_r() fails on extreme negative values (fxbug.dev/78527). +#else EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, cut)); #endif +#endif } } @@ -1026,7 +1047,7 @@ TEST(MakeTime, LocalTimeLibC) { // 1) we know how to change the time zone used by localtime()/mktime(), // 2) cctz and localtime()/mktime() will use similar-enough tzdata, and // 3) we have some idea about how mktime() behaves during transitions. -#if defined(__linux__) && !defined(__ANDROID__) +#if defined(__linux__) && defined(__GLIBC__) && !defined(__ANDROID__) const char* const ep = getenv("TZ"); std::string tz_name = (ep != nullptr) ? ep : ""; for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { @@ -1165,6 +1186,44 @@ TEST(PrevTransition, AmericaNewYork) { // We have a transition but we don't know which one. } +TEST(NextTransition, Scan) { + for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { + time_zone tz; + if (!load_time_zone(*np, &tz)) { + continue; // tolerate kTimeZoneNames/zoneinfo skew + } + SCOPED_TRACE(testing::Message() << "In " << *np); + + auto tp = time_point<absl::time_internal::cctz::seconds>::min(); + time_zone::civil_transition trans; + while (tz.next_transition(tp, &trans)) { + time_zone::civil_lookup from_cl = tz.lookup(trans.from); + EXPECT_NE(from_cl.kind, time_zone::civil_lookup::REPEATED); + time_zone::civil_lookup to_cl = tz.lookup(trans.to); + EXPECT_NE(to_cl.kind, time_zone::civil_lookup::SKIPPED); + + auto trans_tp = to_cl.trans; + time_zone::absolute_lookup trans_al = tz.lookup(trans_tp); + EXPECT_EQ(trans_al.cs, trans.to); + auto pre_trans_tp = trans_tp - absl::time_internal::cctz::seconds(1); + time_zone::absolute_lookup pre_trans_al = tz.lookup(pre_trans_tp); + EXPECT_EQ(pre_trans_al.cs + 1, trans.from); + + auto offset_delta = trans_al.offset - pre_trans_al.offset; + EXPECT_EQ(offset_delta, trans.to - trans.from); + if (offset_delta == 0) { + // This "transition" is only an is_dst or abbr change. + EXPECT_EQ(to_cl.kind, time_zone::civil_lookup::UNIQUE); + if (trans_al.is_dst == pre_trans_al.is_dst) { + EXPECT_STRNE(trans_al.abbr, pre_trans_al.abbr); + } + } + + tp = trans_tp; // continue scan from transition + } + } +} + TEST(TimeZoneEdgeCase, AmericaNewYork) { const time_zone tz = LoadZone("America/New_York"); diff --git a/absl/time/internal/cctz/src/tzfile.h b/absl/time/internal/cctz/src/tzfile.h index 269fa36c..31e85982 100644 --- a/absl/time/internal/cctz/src/tzfile.h +++ b/absl/time/internal/cctz/src/tzfile.h @@ -43,7 +43,7 @@ struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ + char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ char tzh_reserved[15]; /* reserved; must be zero */ char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ diff --git a/absl/time/internal/cctz/src/zone_info_source.cc b/absl/time/internal/cctz/src/zone_info_source.cc index 72095339..5ab5a59e 100644 --- a/absl/time/internal/cctz/src/zone_info_source.cc +++ b/absl/time/internal/cctz/src/zone_info_source.cc @@ -65,7 +65,7 @@ ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; -#if defined(_M_IX86) +#if defined(_M_IX86) || defined(_M_ARM) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ @@ -83,8 +83,7 @@ ZoneInfoSourceFactory default_factory = DefaultFactory; "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ "@@ZA") -#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM) || \ - defined(_M_ARM64) +#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ diff --git a/absl/time/internal/cctz/testdata/README.zoneinfo b/absl/time/internal/cctz/testdata/README.zoneinfo index 95fb4a91..a41c7b88 100644 --- a/absl/time/internal/cctz/testdata/README.zoneinfo +++ b/absl/time/internal/cctz/testdata/README.zoneinfo @@ -13,7 +13,12 @@ New versions can be generated using the following shell script. trap "rm -fr ${DESTDIR}" 0 2 15 ( cd ${DESTDIR} - git clone https://github.com/eggert/tz.git + if [ -n "${USE_GLOBAL_TZ}" ] + then + git clone -b global-tz https://github.com/JodaOrg/global-tz.git tz + else + git clone https://github.com/eggert/tz.git + fi make --directory=tz \ install DESTDIR=${DESTDIR} \ DATAFORM=vanguard \ diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version index 1d590958..ca002de2 100644 --- a/absl/time/internal/cctz/testdata/version +++ b/absl/time/internal/cctz/testdata/version @@ -1 +1 @@ -2021a +2022a diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra Binary files differindex c39ae382..8906e88c 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra +++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba Binary files differindex d6ddf7d8..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan Binary files differindex c8287152..9154643f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados Binary files differindex 9d3afa6a..720c9863 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon Binary files differindex 7096b69a..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour Binary files differindex c8287152..9154643f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston Binary files differindex 9d69a0ab..c2bd2f94 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao Binary files differindex d6ddf7d8..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana Binary files differindex ebd85d0f..bcc66881 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk Binary files differindex d6ddf7d8..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes Binary files differindex d6ddf7d8..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau Binary files differindex 2ef2aa89..fe6be8ea 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas Binary files differindex 5c9a20b9..c0421040 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago Binary files differindex 8d603226..cde8dbbf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin Binary files differindex f4fe5903..47b4dc34 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin +++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville Binary files differindex c0cfc85a..5d8fc3a1 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa Binary files differindex 97d80d75..01c47ccb 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa +++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman Binary files differindex 1bd09fef..d97d308d 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza Binary files differindex 58e9fdf4..effc4df5 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron Binary files differindex aeda06b5..aa52bd26 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron +++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores Binary files differindex b7f75a9c..e6e2616e 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira Binary files differindex 7c3a49c0..cf965c3f 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira +++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental Binary files differindex 8d603226..cde8dbbf 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental +++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev Binary files differindex 8f83cefb..4e026859 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon Binary files differindex 64841661..f0c70b69 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol Binary files differindex 88a6f3bd..40d23c02 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod Binary files differindex a5755685..d4c35914 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye Binary files differindex 4ea8dae4..71819a5a 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye +++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia Binary files differindex 244af26f..a6b835aa 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury Binary files differindex b22ab147..2b6a0608 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji Binary files differindex e3934e42..8b2dd52b 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton Binary files differnew file mode 100644 index 00000000..2b6a0608 --- /dev/null +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue Binary files differindex 7b357935..be874e24 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga Binary files differindex 143a1883..7220bda0 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu Binary files differindex 54aeb0ff..f28c8401 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu +++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Portugal b/absl/time/internal/cctz/testdata/zoneinfo/Portugal Binary files differindex 64841661..f0c70b69 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/Portugal +++ b/absl/time/internal/cctz/testdata/zoneinfo/Portugal diff --git a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab index 396e4d38..c614be81 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +++ b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab @@ -40,11 +40,9 @@ AL +4120+01950 Europe/Tirane AM +4011+04430 Asia/Yerevan AQ -6617+11031 Antarctica/Casey Casey AQ -6835+07758 Antarctica/Davis Davis -AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville AQ -6736+06253 Antarctica/Mawson Mawson AQ -6448-06406 Antarctica/Palmer Palmer AQ -6734-06808 Antarctica/Rothera Rothera -AQ -690022+0393524 Antarctica/Syowa Syowa AQ -720041+0023206 Antarctica/Troll Troll AQ -7824+10654 Antarctica/Vostok Vostok AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF) @@ -97,7 +95,6 @@ BR +0249-06040 America/Boa_Vista Roraima BR -0308-06001 America/Manaus Amazonas (east) BR -0640-06952 America/Eirunepe Amazonas (west) BR -0958-06748 America/Rio_Branco Acre -BS +2505-07721 America/Nassau BT +2728+08939 Asia/Thimphu BY +5354+02734 Europe/Minsk BZ +1730-08812 America/Belize @@ -106,13 +103,11 @@ CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton) CA +4606-06447 America/Moncton Atlantic - New Brunswick CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas) -CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore) -CA +4339-07923 America/Toronto Eastern - ON, QC (most areas) +CA,BS +4339-07923 America/Toronto Eastern - ON, QC (most areas), Bahamas CA +4901-08816 America/Nipigon Eastern - ON, QC (no DST 1967-73) CA +4823-08915 America/Thunder_Bay Eastern - ON (Thunder Bay) CA +6344-06828 America/Iqaluit Eastern - NU (most east areas) CA +6608-06544 America/Pangnirtung Eastern - NU (Pangnirtung) -CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H) CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba CA +4843-09434 America/Rainy_River Central - ON (Rainy R, Ft Frances) CA +744144-0944945 America/Resolute Central - NU (Resolute) @@ -123,7 +118,6 @@ CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W) CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) CA +6227-11421 America/Yellowknife Mountain - NT (central) CA +682059-1334300 America/Inuvik Mountain - NT (west) -CA +4906-11631 America/Creston MST - BC (Creston) CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson) CA +6043-13503 America/Whitehorse MST - Yukon (east) @@ -131,7 +125,7 @@ CA +6404-13925 America/Dawson MST - Yukon (west) CA +4916-12307 America/Vancouver Pacific - BC (most areas) CC -1210+09655 Indian/Cocos CH,DE,LI +4723+00832 Europe/Zurich Swiss time -CI,BF,GM,GN,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan +CI,BF,GH,GM,GN,ML,MR,SH,SL,SN,TG +0519-00402 Africa/Abidjan CK -2114-15946 Pacific/Rarotonga CL -3327-07040 America/Santiago Chile (most areas) CL -5309-07055 America/Punta_Arenas Region of Magallanes @@ -142,7 +136,6 @@ CO +0436-07405 America/Bogota CR +0956-08405 America/Costa_Rica CU +2308-08222 America/Havana CV +1455-02331 Atlantic/Cape_Verde -CW,AW,BQ,SX +1211-06900 America/Curacao CX -1025+10543 Indian/Christmas CY +3510+03322 Asia/Nicosia Cyprus (most areas) CY +3507+03357 Asia/Famagusta Northern Cyprus @@ -170,7 +163,6 @@ FR +4852+00220 Europe/Paris GB,GG,IM,JE +513030-0000731 Europe/London GE +4143+04449 Asia/Tbilisi GF +0456-05220 America/Cayenne -GH +0533-00013 Africa/Accra GI +3608-00521 Europe/Gibraltar GL +6411-05144 America/Nuuk Greenland (most areas) GL +7646-01840 America/Danmarkshavn National Park (east coast) @@ -204,7 +196,7 @@ JP +353916+1394441 Asia/Tokyo KE,DJ,ER,ET,KM,MG,SO,TZ,UG,YT -0117+03649 Africa/Nairobi KG +4254+07436 Asia/Bishkek KI +0125+17300 Pacific/Tarawa Gilbert Islands -KI -0308-17105 Pacific/Enderbury Phoenix Islands +KI -0247-17143 Pacific/Kanton Phoenix Islands KI +0152-15720 Pacific/Kiritimati Line Islands KP +3901+12545 Asia/Pyongyang KR +3733+12658 Asia/Seoul @@ -262,19 +254,19 @@ NR -0031+16655 Pacific/Nauru NU -1901-16955 Pacific/Niue NZ,AQ -3652+17446 Pacific/Auckland New Zealand time NZ -4357-17633 Pacific/Chatham Chatham Islands -PA,KY +0858-07932 America/Panama +PA,CA,KY +0858-07932 America/Panama EST - Panama, Cayman, ON (Atikokan), NU (Coral H) PE -1203-07703 America/Lima PF -1732-14934 Pacific/Tahiti Society Islands PF -0900-13930 Pacific/Marquesas Marquesas Islands PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas) +PG,AQ -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas), Dumont d'Urville PG -0613+15534 Pacific/Bougainville Bougainville PH +1435+12100 Asia/Manila PK +2452+06703 Asia/Karachi PL +5215+02100 Europe/Warsaw PM +4703-05620 America/Miquelon PN -2504-13005 Pacific/Pitcairn -PR +182806-0660622 America/Puerto_Rico +PR,AG,CA,AI,AW,BL,BQ,CW,DM,GD,GP,KN,LC,MF,MS,SX,TT,VC,VG,VI +182806-0660622 America/Puerto_Rico AST PS +3130+03428 Asia/Gaza Gaza Strip PS +313200+0350542 Asia/Hebron West Bank PT +3843-00908 Europe/Lisbon Portugal (mainland) @@ -314,12 +306,12 @@ RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea -SA,KW,YE +2438+04643 Asia/Riyadh +SA,AQ,KW,YE +2438+04643 Asia/Riyadh Arabia, Syowa SB -0932+16012 Pacific/Guadalcanal SC -0440+05528 Indian/Mahe SD +1536+03232 Africa/Khartoum SE +5920+01803 Europe/Stockholm -SG +0117+10351 Asia/Singapore +SG,MY +0117+10351 Asia/Singapore Singapore, peninsular Malaysia SR +0550-05510 America/Paramaribo SS +0451+03137 Africa/Juba ST +0020+00644 Africa/Sao_Tome @@ -334,9 +326,8 @@ TK -0922-17114 Pacific/Fakaofo TL -0833+12535 Asia/Dili TM +3757+05823 Asia/Ashgabat TN +3648+01011 Africa/Tunis -TO -2110-17510 Pacific/Tongatapu +TO -210800-1751200 Pacific/Tongatapu TR +4101+02858 Europe/Istanbul -TT,AG,AI,BL,DM,GD,GP,KN,LC,MF,MS,VC,VG,VI +1039-06131 America/Port_of_Spain TV -0831+17913 Pacific/Funafuti TW +2503+12130 Asia/Taipei UA +5026+03031 Europe/Kiev Ukraine (most areas) @@ -362,7 +353,7 @@ US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) US +394421-1045903 America/Denver Mountain (most areas) US +433649-1161209 America/Boise Mountain - ID (south); OR (east) -US +332654-1120424 America/Phoenix MST - Arizona (except Navajo) +US,CA +332654-1120424 America/Phoenix MST - Arizona (except Navajo), Creston BC US +340308-1181434 America/Los_Angeles Pacific US +611305-1495401 America/Anchorage Alaska (most areas) US +581807-1342511 America/Juneau Alaska - Juneau area |