summaryrefslogtreecommitdiff
path: root/absl/time/internal/cctz
diff options
context:
space:
mode:
authorGravatar Pirate Praveen <praveen@debian.org>2023-03-06 20:25:41 +0530
committerGravatar Pirate Praveen <praveen@debian.org>2023-03-06 20:25:41 +0530
commit079dd8737bbaaaeeca3a95c2b858a62d8a620d5a (patch)
tree6af54966e17bcfe48ecdb0b5cdf43cc953d5358c /absl/time/internal/cctz
parent2bbc47f307f1e24f3f44a108d571bffa5a3faa63 (diff)
parentf5afcb784c9b1c501c1144b7aab84555881ca871 (diff)
Merge tag '20220623.1-1' into bullseye-backports-staging
Diffstat (limited to 'absl/time/internal/cctz')
-rw-r--r--absl/time/internal/cctz/BUILD.bazel14
-rw-r--r--absl/time/internal/cctz/include/cctz/civil_time_detail.h18
-rw-r--r--absl/time/internal/cctz/include/cctz/time_zone.h113
-rw-r--r--absl/time/internal/cctz/src/cctz_benchmark.cc1
-rw-r--r--absl/time/internal/cctz/src/time_zone_fixed.cc2
-rw-r--r--absl/time/internal/cctz/src/time_zone_format_test.cc101
-rw-r--r--absl/time/internal/cctz/src/time_zone_if.h3
-rw-r--r--absl/time/internal/cctz/src/time_zone_info.cc104
-rw-r--r--absl/time/internal/cctz/src/time_zone_lookup.cc49
-rw-r--r--absl/time/internal/cctz/src/time_zone_lookup_test.cc65
-rw-r--r--absl/time/internal/cctz/src/tzfile.h2
-rw-r--r--absl/time/internal/cctz/src/zone_info_source.cc5
-rw-r--r--absl/time/internal/cctz/testdata/README.zoneinfo7
-rw-r--r--absl/time/internal/cctz/testdata/version2
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Africa/Accrabin700 -> 130 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Anguillabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Antiguabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Arubabin151 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Atikokanbin224 -> 149 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Barbadosbin231 -> 278 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablonbin205 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbourbin224 -> 149 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Crestonbin158 -> 240 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Curacaobin151 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Dominicabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Grenadabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupebin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Guyanabin172 -> 181 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijkbin151 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princesbin151 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Marigotbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Montserratbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Nassaubin1006 -> 1717 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spainbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenasbin1209 -> 1209 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Santiagobin1282 -> 1282 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemybin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/St_Kittsbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/St_Luciabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomasbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincentbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Tortolabin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/America/Virginbin130 -> 177 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrvillebin152 -> 154 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowabin133 -> 133 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Asia/Ammanbin787 -> 922 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Asia/Gazabin1213 -> 1240 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebronbin1231 -> 1258 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azoresbin1435 -> 1453 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeirabin1435 -> 1453 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Chile/Continentalbin1282 -> 1282 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Europe/Kievbin549 -> 558 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbonbin1436 -> 1454 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopolbin865 -> 865 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorodbin530 -> 539 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhyebin560 -> 569 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apiabin268 -> 407 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderburybin172 -> 172 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fijibin419 -> 428 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kantonbin0 -> 172 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niuebin175 -> 154 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotongabin391 -> 406 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapubin237 -> 237 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/Portugalbin1436 -> 1454 bytes
-rw-r--r--absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab29
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
index c39ae382..8906e88c 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Accra
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Anguilla
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Antigua
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba
index d6ddf7d8..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Aruba
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan
index c8287152..9154643f 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Atikokan
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados
index 9d3afa6a..720c9863 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Barbados
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon
index 7096b69a..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Blanc-Sablon
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour
index c8287152..9154643f 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Coral_Harbour
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston
index 9d69a0ab..c2bd2f94 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Creston
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Creston
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao
index d6ddf7d8..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Curacao
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Dominica
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Grenada
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guadeloupe
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana
index ebd85d0f..bcc66881 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Guyana
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk
index d6ddf7d8..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Kralendijk
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes
index d6ddf7d8..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Lower_Princes
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Marigot
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Montserrat
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau
index 2ef2aa89..fe6be8ea 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Nassau
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain b/absl/time/internal/cctz/testdata/zoneinfo/America/Port_of_Spain
index 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
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas
index 5c9a20b9..c0421040 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Punta_Arenas
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago
index 8d603226..cde8dbbf 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Santiago
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Barthelemy
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Kitts
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Lucia
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Thomas
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/St_Vincent
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Tortola
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin
index f4fe5903..47b4dc34 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin
+++ b/absl/time/internal/cctz/testdata/zoneinfo/America/Virgin
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville
index c0cfc85a..5d8fc3a1 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/DumontDUrville
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa
index 97d80d75..01c47ccb 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Antarctica/Syowa
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman
index 1bd09fef..d97d308d 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Amman
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
index 58e9fdf4..effc4df5 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Gaza
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
index aeda06b5..aa52bd26 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hebron
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores
index b7f75a9c..e6e2616e 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Azores
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira
index 7c3a49c0..cf965c3f 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Atlantic/Madeira
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental
index 8d603226..cde8dbbf 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Chile/Continental
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev
index 8f83cefb..4e026859 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Kiev
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon
index 64841661..f0c70b69 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Lisbon
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol
index 88a6f3bd..40d23c02 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Simferopol
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod
index a5755685..d4c35914 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Uzhgorod
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye
index 4ea8dae4..71819a5a 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Europe/Zaporozhye
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia
index 244af26f..a6b835aa 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Apia
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury
index b22ab147..2b6a0608 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Enderbury
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji
index e3934e42..8b2dd52b 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Fiji
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton
new file mode 100644
index 00000000..2b6a0608
--- /dev/null
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kanton
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue
index 7b357935..be874e24 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Niue
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga
index 143a1883..7220bda0 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Rarotonga
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu
index 54aeb0ff..f28c8401 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Tongatapu
Binary files differ
diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Portugal b/absl/time/internal/cctz/testdata/zoneinfo/Portugal
index 64841661..f0c70b69 100644
--- a/absl/time/internal/cctz/testdata/zoneinfo/Portugal
+++ b/absl/time/internal/cctz/testdata/zoneinfo/Portugal
Binary files differ
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