New Upstream Snapshot - cctz

Ready changes

Summary

Merged new upstream version: 2.3+git20220321.1.455b5f5 (was: 2.3+dfsg1).

Resulting package

Built on 2022-03-31T10:54 (took 19m50s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots libcctz-devapt install -t fresh-snapshots libcctz-docapt install -t fresh-snapshots libcctz2-dbgsymapt install -t fresh-snapshots libcctz2

Lintian Result

Diff

diff --git a/BUILD b/BUILD
index 765cb87..cd0ca3e 100644
--- a/BUILD
+++ b/BUILD
@@ -12,19 +12,19 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
-licenses(["notice"])  # Apache License
+licenses(["notice"])
 
 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",
     ],
 )
 
@@ -65,6 +65,7 @@ cc_library(
         "include/cctz/time_zone.h",
         "include/cctz/zone_info_source.h",
     ],
+    includes = ["include"],
     linkopts = select({
         "//:osx": [
             "-framework Foundation",
@@ -74,13 +75,17 @@ cc_library(
         ],
         "//conditions:default": [],
     }),
-    includes = ["include"],
     visibility = ["//visibility:public"],
     deps = [":civil_time"],
 )
 
 ### tests
 
+test_suite(
+    name = "all_tests",
+    visibility = ["//visibility:public"],
+)
+
 cc_test(
     name = "civil_time_test",
     size = "small",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e8b2f34..19cce31 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,9 @@
 cmake_minimum_required(VERSION 2.8.12)
 
+if (POLICY CMP0025)
+  cmake_policy(SET CMP0025 NEW)
+endif()
+
 project(cctz)
 
 set(CMAKE_MODULE_PATH
@@ -96,7 +100,9 @@ target_include_directories(cctz PUBLIC
 set_target_properties(cctz PROPERTIES
   PUBLIC_HEADER "${CCTZ_HDRS}"
   )
-target_link_libraries(cctz PUBLIC $<$<PLATFORM_ID:Darwin>:${CoreFoundation}>)  
+if(APPLE)
+  target_link_libraries(cctz PUBLIC ${CoreFoundation})
+endif()
 add_library(cctz::cctz ALIAS cctz)
 
 if (BUILD_TOOLS)
@@ -159,13 +165,14 @@ include(GNUInstallDirs)
 install(TARGETS cctz
   EXPORT ${PROJECT_NAME}-targets
   PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cctz
+  RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
   )
 if (BUILD_TOOLS)
   install(TARGETS time_tool
     EXPORT ${PROJECT_NAME}-targets
-    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    DESTINATION ${CMAKE_INSTALL_BINDIR}
     )
 endif()
 set(CMAKE_INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
@@ -177,4 +184,10 @@ install(FILES cmake/${PROJECT_NAME}-config.cmake
   DESTINATION ${CMAKE_INSTALL_CONFIGDIR}
   )
 
-feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+if (CMAKE_VERSION VERSION_LESS "3.8")
+  set(quiet_on_empty "")
+else()
+  set(quiet_on_empty QUIET_ON_EMPTY)
+endif()
+
+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES ${quiet_on_empty})
diff --git a/WORKSPACE b/WORKSPACE
index 6676288..16d3f2e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -5,13 +5,23 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 # GoogleTest/GoogleMock framework. Used by most unit-tests.
 http_archive(
     name = "com_google_googletest",
-    urls = ["https://github.com/google/googletest/archive/master.zip"],
-    strip_prefix = "googletest-master",
+    sha256 = "353571c2440176ded91c2de6d6cd88ddd41401d14692ec1f99e35d013feda55a",
+    strip_prefix = "googletest-release-1.11.0",
+    urls = ["https://github.com/google/googletest/archive/release-1.11.0.zip"],
 )
 
 # Google Benchmark library.
 http_archive(
     name = "com_github_google_benchmark",
-    urls = ["https://github.com/google/benchmark/archive/master.zip"],
-    strip_prefix = "benchmark-master",
+    sha256 = "30f2e5156de241789d772dd8b130c1cb5d33473cc2f29e4008eab680df7bd1f0",
+    strip_prefix = "benchmark-1.5.5",
+    urls = ["https://github.com/google/benchmark/archive/v1.5.5.zip"],
+)
+
+# Bazel platform rules.
+http_archive(
+    name = "platforms",
+    sha256 = "b601beaf841244de5c5a50d2b2eddd34839788000fa1be4260ce6603ca0d8eb7",
+    strip_prefix = "platforms-98939346da932eef0b54cf808622f5bb0928f00b",
+    urls = ["https://github.com/bazelbuild/platforms/archive/98939346da932eef0b54cf808622f5bb0928f00b.zip"],
 )
diff --git a/debian/changelog b/debian/changelog
index 5fdb2f5..0da5b08 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+cctz (2.3+git20220321.1.455b5f5-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 31 Mar 2022 10:50:23 -0000
+
 cctz (2.3+dfsg1-3) unstable; urgency=medium
 
   * [143a67c] Do not run benchmark tests on mips
diff --git a/debian/patches/0001-Compile-shared-lib-and-install-it.patch b/debian/patches/0001-Compile-shared-lib-and-install-it.patch
index d4ad8ef..314ec25 100644
--- a/debian/patches/0001-Compile-shared-lib-and-install-it.patch
+++ b/debian/patches/0001-Compile-shared-lib-and-install-it.patch
@@ -6,11 +6,11 @@ Subject: [PATCH 1/2] Compile shared lib and install it
  CMakeLists.txt | 10 +++++++++-
  1 file changed, 9 insertions(+), 1 deletion(-)
 
-Index: cctz-2.3/CMakeLists.txt
+Index: cctz/CMakeLists.txt
 ===================================================================
---- cctz-2.3.orig/CMakeLists.txt
-+++ cctz-2.3/CMakeLists.txt
-@@ -68,7 +68,7 @@ set(CCTZ_HDRS
+--- cctz.orig/CMakeLists.txt
++++ cctz/CMakeLists.txt
+@@ -72,7 +72,7 @@ set(CCTZ_HDRS
    include/cctz/zone_info_source.h
    include/cctz/civil_time.h
    )
@@ -19,9 +19,9 @@ Index: cctz-2.3/CMakeLists.txt
    src/civil_time_detail.cc
    src/time_zone_fixed.cc
    src/time_zone_fixed.h
-@@ -98,6 +98,14 @@ set_target_properties(cctz PROPERTIES
-   )
- target_link_libraries(cctz PUBLIC $<$<PLATFORM_ID:Darwin>:${CoreFoundation}>)  
+@@ -104,6 +104,14 @@ if(APPLE)
+   target_link_libraries(cctz PUBLIC ${CoreFoundation})
+ endif()
  add_library(cctz::cctz ALIAS cctz)
 +set_target_properties(cctz PROPERTIES
 +    OUTPUT_NAME "cctz"
diff --git a/debian/patches/0002-Enable-tests-for-Debian.patch b/debian/patches/0002-Enable-tests-for-Debian.patch
index b154e58..0a48d83 100644
--- a/debian/patches/0002-Enable-tests-for-Debian.patch
+++ b/debian/patches/0002-Enable-tests-for-Debian.patch
@@ -10,7 +10,7 @@ Index: cctz/CMakeLists.txt
 ===================================================================
 --- cctz.orig/CMakeLists.txt
 +++ cctz/CMakeLists.txt
-@@ -21,19 +21,15 @@ if (BUILD_TESTING)
+@@ -25,19 +25,15 @@ if (BUILD_TESTING)
      URL "https://github.com/google/benchmark"
    )
  
@@ -38,7 +38,7 @@ Index: cctz/CMakeLists.txt
  
    find_package(Threads)
    set_package_properties(Threads PROPERTIES
-@@ -118,7 +114,7 @@ if (BUILD_EXAMPLES)
+@@ -124,7 +120,7 @@ if (BUILD_EXAMPLES)
  endif()
  
  if (BUILD_TESTING)
@@ -47,7 +47,7 @@ Index: cctz/CMakeLists.txt
    cctz_target_set_cxx_standard(civil_time_test)
    target_include_directories(civil_time_test PRIVATE ${GTEST_INCLUDE_DIRS})
    target_link_libraries(civil_time_test
-@@ -128,7 +124,9 @@ if (BUILD_TESTING)
+@@ -134,7 +130,9 @@ if (BUILD_TESTING)
      )
    add_test(civil_time_test civil_time_test)
  
@@ -58,7 +58,7 @@ Index: cctz/CMakeLists.txt
    cctz_target_set_cxx_standard(time_zone_lookup_test)
    target_include_directories(time_zone_lookup_test PRIVATE ${GTEST_INCLUDE_DIRS})
    target_link_libraries(time_zone_lookup_test
-@@ -138,12 +136,14 @@ if (BUILD_TESTING)
+@@ -144,12 +142,14 @@ if (BUILD_TESTING)
      )
    add_test(time_zone_lookup_test time_zone_lookup_test)
  
@@ -75,7 +75,7 @@ Index: cctz/CMakeLists.txt
      )
    add_test(time_zone_format_test time_zone_format_test)
  
-@@ -160,6 +160,10 @@ if (BUILD_TESTING)
+@@ -166,6 +166,10 @@ if (BUILD_TESTING)
    add_executable(cctz_benchmark src/cctz_benchmark.cc)
    cctz_target_set_cxx_standard(cctz_benchmark)
    target_link_libraries(cctz_benchmark cctz::cctz benchmark::benchmark_main)
diff --git a/debian/patches/use_system_zoneinfo.patch b/debian/patches/use_system_zoneinfo.patch
index a6564d6..48ba29f 100644
--- a/debian/patches/use_system_zoneinfo.patch
+++ b/debian/patches/use_system_zoneinfo.patch
@@ -2,11 +2,11 @@ Description: use zoneinfo shipped with the system
 Author: Anton Gladky <gladk@debian.org>
 Last-Update: 2017-11-15
 
-Index: cctz-2.3/CMakeLists.txt
+Index: cctz/CMakeLists.txt
 ===================================================================
---- cctz-2.3.orig/CMakeLists.txt
-+++ cctz-2.3/CMakeLists.txt
-@@ -154,7 +154,7 @@ if (BUILD_TESTING)
+--- cctz.orig/CMakeLists.txt
++++ cctz/CMakeLists.txt
+@@ -160,7 +160,7 @@ if (BUILD_TESTING)
        time_zone_format_test
        time_zone_lookup_test
      PROPERTY
diff --git a/include/cctz/civil_time.h b/include/cctz/civil_time.h
index 7366ccc..57bd86c 100644
--- a/include/cctz/civil_time.h
+++ b/include/cctz/civil_time.h
@@ -148,7 +148,7 @@ namespace cctz {
 //
 // All civil-time types have accessors for all six of the civil-time fields:
 // year, month, day, hour, minute, and second. Recall that fields inferior to
-// the type's aligment will be set to their minimum valid value.
+// the type's alignment will be set to their minimum valid value.
 //
 //   civil_day d(2015, 6, 28);
 //   // d.year() == 2015
@@ -277,7 +277,7 @@ using civil_second = detail::civil_second;
 //
 using detail::weekday;
 
-// Returns the weekday for the given civil_day.
+// Returns the weekday for the given civil-time value.
 //
 //   civil_day a(2015, 8, 13);
 //   weekday wd = get_weekday(a);  // wd == weekday::thursday
@@ -304,14 +304,14 @@ using detail::get_weekday;
 //
 //   civil_day d = ...
 //   // Gets the following Thursday if d is not already Thursday
-//   civil_day thurs1 = prev_weekday(d, weekday::thursday) + 7;
+//   civil_day thurs1 = next_weekday(d - 1, weekday::thursday);
 //   // Gets the previous Thursday if d is not already Thursday
-//   civil_day thurs2 = next_weekday(d, weekday::thursday) - 7;
+//   civil_day thurs2 = prev_weekday(d + 1, weekday::thursday);
 //
 using detail::next_weekday;
 using detail::prev_weekday;
 
-// Returns the day-of-year for the given civil_day.
+// Returns the day-of-year for the given civil-time value.
 //
 //   civil_day a(2015, 1, 1);
 //   int yd_jan_1 = get_yearday(a);   // yd_jan_1 = 1
diff --git a/include/cctz/civil_time_detail.h b/include/cctz/civil_time_detail.h
index decc5f2..2dab664 100644
--- a/include/cctz/civil_time_detail.h
+++ b/include/cctz/civil_time_detail.h
@@ -21,7 +21,7 @@
 #include <type_traits>
 
 // Disable constexpr support unless we are in C++14 mode.
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 #define CONSTEXPR_D constexpr  // data
 #define CONSTEXPR_F constexpr  // function
 #define CONSTEXPR_M constexpr  // member
@@ -79,14 +79,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 {
@@ -101,54 +100,69 @@ CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept {
 
 CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd,
                          hour_t hh, minute_t mm, second_t ss) noexcept {
-  y += (cd / 146097) * 400;
+  year_t ey = y % 400;
+  const year_t oey = ey;
+  ey += (cd / 146097) * 400;
   cd %= 146097;
   if (cd < 0) {
-    y -= 400;
+    ey -= 400;
     cd += 146097;
   }
-  y += (d / 146097) * 400;
+  ey += (d / 146097) * 400;
   d = d % 146097 + cd;
   if (d > 0) {
     if (d > 146097) {
-      y += 400;
+      ey += 400;
       d -= 146097;
     }
   } else {
     if (d > -365) {
       // We often hit the previous year when stepping a civil time backwards,
       // so special case it to avoid counting up by 100/4/1-year chunks.
-      y -= 1;
-      d += days_per_year(y, m);
+      ey -= 1;
+      d += days_per_year(ey, m);
     } else {
-      y -= 400;
+      ey -= 400;
       d += 146097;
     }
   }
   if (d > 365) {
-    for (int n = days_per_century(y, m); d > n; n = days_per_century(y, m)) {
+    int yi = year_index(ey, m);  // Index into Gregorian 400 year cycle.
+    for (;;) {
+      int n = days_per_century(yi);
+      if (d <= n) break;
       d -= n;
-      y += 100;
+      ey += 100;
+      yi += 100;
+      if (yi >= 400) yi -= 400;
     }
-    for (int n = days_per_4years(y, m); d > n; n = days_per_4years(y, m)) {
+    for (;;) {
+      int n = days_per_4years(yi);
+      if (d <= n) break;
       d -= n;
-      y += 4;
+      ey += 4;
+      yi += 4;
+      if (yi >= 400) yi -= 400;
     }
-    for (int n = days_per_year(y, m); d > n; n = days_per_year(y, m)) {
+    for (;;) {
+      int n = days_per_year(ey, m);
+      if (d <= n) break;
       d -= n;
-      ++y;
+      ++ey;
     }
   }
   if (d > 28) {
-    for (int n = days_per_month(y, m); d > n; n = days_per_month(y, m)) {
+    for (;;) {
+      int n = days_per_month(ey, m);
+      if (d <= n) break;
       d -= n;
       if (++m > 12) {
-        ++y;
+        ++ey;
         m = 1;
       }
     }
   }
-  return fields(y, m, static_cast<day_t>(d), hh, mm, ss);
+  return fields(y + (ey - oey), m, static_cast<day_t>(d), hh, mm, ss);
 }
 CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd,
                          hour_t hh, minute_t mm, second_t ss) noexcept {
@@ -372,16 +386,10 @@ class civil_time {
 
   // Assigning arithmetic.
   CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept {
-    f_ = step(T{}, f_, n);
-    return *this;
+    return *this = *this + n;
   }
   CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept {
-    if (n != (std::numeric_limits<diff_t>::min)()) {
-      f_ = step(T{}, f_, -n);
-    } else {
-      f_ = step(T{}, step(T{}, f_, -(n + 1)), 1);
-    }
-    return *this;
+    return *this = *this - n;
   }
   CONSTEXPR_M civil_time& operator++() noexcept {
     return *this += 1;
@@ -402,13 +410,15 @@ class civil_time {
 
   // Binary arithmetic operators.
   friend CONSTEXPR_F civil_time operator+(civil_time a, diff_t n) noexcept {
-    return a += n;
+    return civil_time(step(T{}, a.f_, n));
   }
   friend CONSTEXPR_F civil_time operator+(diff_t n, civil_time a) noexcept {
-    return a += n;
+    return a + n;
   }
   friend CONSTEXPR_F civil_time operator-(civil_time a, diff_t n) noexcept {
-    return a -= n;
+    return n != (std::numeric_limits<diff_t>::min)()
+               ? civil_time(step(T{}, a.f_, -n))
+               : civil_time(step(T{}, step(T{}, a.f_, -(n + 1)), 1));
   }
   friend CONSTEXPR_F diff_t operator-(civil_time lhs, civil_time rhs) noexcept {
     return difference(T{}, lhs.f_, rhs.f_);
@@ -497,7 +507,7 @@ enum class weekday {
   sunday,
 };
 
-CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept {
+CONSTEXPR_F weekday get_weekday(const civil_second& cs) noexcept {
   CONSTEXPR_D weekday k_weekday_by_mon_off[13] = {
       weekday::monday,    weekday::tuesday,  weekday::wednesday,
       weekday::thursday,  weekday::friday,   weekday::saturday,
@@ -508,30 +518,60 @@ CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept {
   CONSTEXPR_D int k_weekday_offsets[1 + 12] = {
       -1, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4,
   };
-  year_t wd = 2400 + (cd.year() % 400) - (cd.month() < 3);
+  year_t wd = 2400 + (cs.year() % 400) - (cs.month() < 3);
   wd += wd / 4 - wd / 100 + wd / 400;
-  wd += k_weekday_offsets[cd.month()] + cd.day();
+  wd += k_weekday_offsets[cs.month()] + cs.day();
   return k_weekday_by_mon_off[wd % 7 + 6];
 }
 
 ////////////////////////////////////////////////////////////////////////
 
 CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept {
-  do { cd += 1; } while (get_weekday(cd) != wd);
-  return cd;
+  CONSTEXPR_D weekday k_weekdays_forw[14] = {
+      weekday::monday,    weekday::tuesday,  weekday::wednesday,
+      weekday::thursday,  weekday::friday,   weekday::saturday,
+      weekday::sunday,    weekday::monday,   weekday::tuesday,
+      weekday::wednesday, weekday::thursday, weekday::friday,
+      weekday::saturday,  weekday::sunday,
+  };
+  weekday base = get_weekday(cd);
+  for (int i = 0;; ++i) {
+    if (base == k_weekdays_forw[i]) {
+      for (int j = i + 1;; ++j) {
+        if (wd == k_weekdays_forw[j]) {
+          return cd + (j - i);
+        }
+      }
+    }
+  }
 }
 
 CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept {
-  do { cd -= 1; } while (get_weekday(cd) != wd);
-  return cd;
+  CONSTEXPR_D weekday k_weekdays_back[14] = {
+      weekday::sunday,   weekday::saturday,  weekday::friday,
+      weekday::thursday, weekday::wednesday, weekday::tuesday,
+      weekday::monday,   weekday::sunday,    weekday::saturday,
+      weekday::friday,   weekday::thursday,  weekday::wednesday,
+      weekday::tuesday,  weekday::monday,
+  };
+  weekday base = get_weekday(cd);
+  for (int i = 0;; ++i) {
+    if (base == k_weekdays_back[i]) {
+      for (int j = i + 1;; ++j) {
+        if (wd == k_weekdays_back[j]) {
+          return cd - (j - i);
+        }
+      }
+    }
+  }
 }
 
-CONSTEXPR_F int get_yearday(const civil_day& cd) noexcept {
+CONSTEXPR_F int get_yearday(const civil_second& cs) noexcept {
   CONSTEXPR_D int k_month_offsets[1 + 12] = {
       -1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
   };
-  const int feb29 = (cd.month() > 2 && impl::is_leap_year(cd.year()));
-  return k_month_offsets[cd.month()] + feb29 + cd.day();
+  const int feb29 = (cs.month() > 2 && impl::is_leap_year(cs.year()));
+  return k_month_offsets[cs.month()] + feb29 + cs.day();
 }
 
 ////////////////////////////////////////////////////////////////////////
diff --git a/include/cctz/time_zone.h b/include/cctz/time_zone.h
index f97ea26..55005f8 100644
--- a/include/cctz/time_zone.h
+++ b/include/cctz/time_zone.h
@@ -22,6 +22,7 @@
 
 #include <chrono>
 #include <cstdint>
+#include <limits>
 #include <string>
 #include <utility>
 
@@ -37,20 +38,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
@@ -274,6 +264,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
@@ -287,6 +291,7 @@ bool parse(const std::string&, const std::string&, const time_zone&,
 //   - %E#f - Fractional seconds with # digits of precision
 //   - %E*f - Fractional seconds with full precision (a literal '*')
 //   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+//   - %ET  - The RFC3339 "date-time" separator "T"
 //
 // Note that %E0S behaves like %S, and %E0f produces no characters. In
 // contrast %E*f always produces at least one digit, which may be '0'.
@@ -316,7 +321,8 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp,
 // returns the corresponding time_point. Uses strftime()-like formatting
 // options, with the same extensions as cctz::format(), but with the
 // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez
-// and %E*z also accept the same inputs.
+// and %E*z also accept the same inputs, which (along with %z) includes
+// 'z' and 'Z' as synonyms for +00:00.  %ET accepts either 'T' or 't'.
 //
 // %Y consumes as many numeric characters as it can, so the matching data
 // should always be terminated with a non-numeric. %E4Y always consumes
@@ -362,15 +368,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
 
 #endif  // CCTZ_TIME_ZONE_H_
diff --git a/src/cctz_benchmark.cc b/src/cctz_benchmark.cc
index 179ae50..9725415 100644
--- a/src/cctz_benchmark.cc
+++ b/src/cctz_benchmark.cc
@@ -45,8 +45,58 @@ void BM_Step_Days(benchmark::State& state) {
 }
 BENCHMARK(BM_Step_Days);
 
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez";
+void BM_GetWeekday(benchmark::State& state) {
+  const cctz::civil_day c(2014, 8, 22);
+  while (state.KeepRunning()) {
+    benchmark::DoNotOptimize(cctz::get_weekday(c));
+  }
+}
+BENCHMARK(BM_GetWeekday);
+
+void BM_NextWeekday(benchmark::State& state) {
+  const cctz::civil_day kStart(2014, 8, 22);
+  const cctz::civil_day kDays[7] = {
+      kStart + 0, kStart + 1, kStart + 2, kStart + 3,
+      kStart + 4, kStart + 5, kStart + 6,
+  };
+  const cctz::weekday kWeekdays[7] = {
+      cctz::weekday::monday,   cctz::weekday::tuesday, cctz::weekday::wednesday,
+      cctz::weekday::thursday, cctz::weekday::friday,  cctz::weekday::saturday,
+      cctz::weekday::sunday,
+  };
+  while (state.KeepRunningBatch(7 * 7)) {
+    for (const auto from : kDays) {
+      for (const auto to : kWeekdays) {
+        benchmark::DoNotOptimize(cctz::next_weekday(from, to));
+      }
+    }
+  }
+}
+BENCHMARK(BM_NextWeekday);
+
+void BM_PrevWeekday(benchmark::State& state) {
+  const cctz::civil_day kStart(2014, 8, 22);
+  const cctz::civil_day kDays[7] = {
+      kStart + 0, kStart + 1, kStart + 2, kStart + 3,
+      kStart + 4, kStart + 5, kStart + 6,
+  };
+  const cctz::weekday kWeekdays[7] = {
+      cctz::weekday::monday,   cctz::weekday::tuesday, cctz::weekday::wednesday,
+      cctz::weekday::thursday, cctz::weekday::friday,  cctz::weekday::saturday,
+      cctz::weekday::sunday,
+  };
+  while (state.KeepRunningBatch(7 * 7)) {
+    for (const auto from : kDays) {
+      for (const auto to : kWeekdays) {
+        benchmark::DoNotOptimize(cctz::prev_weekday(from, to));
+      }
+    }
+  }
+}
+BENCHMARK(BM_PrevWeekday);
+
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez";
 
 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
 const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z";
@@ -229,6 +279,7 @@ const char* const kTimeZoneNames[] = {
   "America/North_Dakota/Beulah",
   "America/North_Dakota/Center",
   "America/North_Dakota/New_Salem",
+  "America/Nuuk",
   "America/Ojinaga",
   "America/Panama",
   "America/Pangnirtung",
@@ -596,6 +647,7 @@ const char* const kTimeZoneNames[] = {
   "Pacific/Guam",
   "Pacific/Honolulu",
   "Pacific/Johnston",
+  "Pacific/Kanton",
   "Pacific/Kiritimati",
   "Pacific/Kosrae",
   "Pacific/Kwajalein",
@@ -940,12 +992,12 @@ void BM_Time_FromCivilDay0_Libc(benchmark::State& state) {
 BENCHMARK(BM_Time_FromCivilDay0_Libc);
 
 const char* const kFormats[] = {
-    RFC1123_full,         // 0
-    RFC1123_no_wday,      // 1
-    RFC3339_full,         // 2
-    RFC3339_sec,          // 3
-    "%Y-%m-%dT%H:%M:%S",  // 4
-    "%Y-%m-%d",           // 5
+    RFC1123_full,           // 0
+    RFC1123_no_wday,        // 1
+    RFC3339_full,           // 2
+    RFC3339_sec,            // 3
+    "%Y-%m-%d%ET%H:%M:%S",  // 4
+    "%Y-%m-%d",             // 5
 };
 const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
 
diff --git a/src/civil_time_test.cc b/src/civil_time_test.cc
index 999f7d4..5ec0ca8 100644
--- a/src/civil_time_test.cc
+++ b/src/civil_time_test.cc
@@ -35,7 +35,7 @@ std::string Format(const T& t) {
 
 }  // namespace
 
-#if __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 // Construction constexpr tests
 
 TEST(CivilTime, Normal) {
@@ -230,6 +230,16 @@ TEST(CivilTime, Difference) {
   static_assert(diff == 365, "Difference");
 }
 
+// NOTE: Run this with --copt=-ftrapv to detect overflow problems.
+TEST(CivilTime, ConstructionWithHugeYear) {
+  constexpr civil_hour h(-9223372036854775807, 1, 1, -1);
+  static_assert(h.year() == -9223372036854775807 - 1,
+                "ConstructionWithHugeYear");
+  static_assert(h.month() == 12, "ConstructionWithHugeYear");
+  static_assert(h.day() == 31, "ConstructionWithHugeYear");
+  static_assert(h.hour() == 23, "ConstructionWithHugeYear");
+}
+
 // NOTE: Run this with --copt=-ftrapv to detect overflow problems.
 TEST(CivilTime, DifferenceWithHugeYear) {
   {
@@ -317,7 +327,7 @@ TEST(CivilTime, YearDay) {
   constexpr int yd = get_yearday(cd);
   static_assert(yd == 28, "YearDay");
 }
-#endif  // __cpp_constexpr >= 201304 || _MSC_VER >= 1910
+#endif  // __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910)
 
 // The remaining tests do not use constexpr.
 
@@ -819,6 +829,8 @@ TEST(CivilTime, Properties) {
   EXPECT_EQ(4, ss.hour());
   EXPECT_EQ(5, ss.minute());
   EXPECT_EQ(6, ss.second());
+  EXPECT_EQ(weekday::tuesday, get_weekday(ss));
+  EXPECT_EQ(34, get_yearday(ss));
 
   civil_minute mm(2015, 2, 3, 4, 5, 6);
   EXPECT_EQ(2015, mm.year());
@@ -827,6 +839,8 @@ TEST(CivilTime, Properties) {
   EXPECT_EQ(4, mm.hour());
   EXPECT_EQ(5, mm.minute());
   EXPECT_EQ(0, mm.second());
+  EXPECT_EQ(weekday::tuesday, get_weekday(mm));
+  EXPECT_EQ(34, get_yearday(mm));
 
   civil_hour hh(2015, 2, 3, 4, 5, 6);
   EXPECT_EQ(2015, hh.year());
@@ -835,6 +849,8 @@ TEST(CivilTime, Properties) {
   EXPECT_EQ(4, hh.hour());
   EXPECT_EQ(0, hh.minute());
   EXPECT_EQ(0, hh.second());
+  EXPECT_EQ(weekday::tuesday, get_weekday(hh));
+  EXPECT_EQ(34, get_yearday(hh));
 
   civil_day d(2015, 2, 3, 4, 5, 6);
   EXPECT_EQ(2015, d.year());
@@ -853,6 +869,8 @@ TEST(CivilTime, Properties) {
   EXPECT_EQ(0, m.hour());
   EXPECT_EQ(0, m.minute());
   EXPECT_EQ(0, m.second());
+  EXPECT_EQ(weekday::sunday, get_weekday(m));
+  EXPECT_EQ(32, get_yearday(m));
 
   civil_year y(2015, 2, 3, 4, 5, 6);
   EXPECT_EQ(2015, y.year());
@@ -861,6 +879,8 @@ TEST(CivilTime, Properties) {
   EXPECT_EQ(0, y.hour());
   EXPECT_EQ(0, y.minute());
   EXPECT_EQ(0, y.second());
+  EXPECT_EQ(weekday::thursday, get_weekday(y));
+  EXPECT_EQ(1, get_yearday(y));
 }
 
 TEST(CivilTime, OutputStream) {
@@ -1033,7 +1053,7 @@ TEST(CivilTime, LeapYears) {
 
 TEST(CivilTime, FirstThursdayInMonth) {
   const civil_day nov1(2014, 11, 1);
-  const civil_day thursday = prev_weekday(nov1, weekday::thursday) + 7;
+  const civil_day thursday = next_weekday(nov1 - 1, weekday::thursday);
   EXPECT_EQ("2014-11-06", Format(thursday));
 
   // Bonus: Date of Thanksgiving in the United States
diff --git a/src/time_tool.cc b/src/time_tool.cc
index 63a0db6..31ce2ba 100644
--- a/src/time_tool.cc
+++ b/src/time_tool.cc
@@ -20,6 +20,7 @@
 #include <cstring>
 #include <ctime>
 #include <iomanip>
+#include <ios>
 #include <iostream>
 #include <limits>
 #include <sstream>
@@ -37,9 +38,9 @@ using seconds = cctz::seconds;
 // parse() specifiers for command-line time arguments.
 const char* const kFormats[] = {
   "%Y   %m   %d   %H   %M   %E*S",
-  "%Y - %m - %d T %H : %M : %E*S",
+  "%Y - %m - %d %ET %H : %M : %E*S",
   "%Y - %m - %d %H : %M : %E*S",
-  "%Y - %m - %d T %H : %M",
+  "%Y - %m - %d %ET %H : %M",
   "%Y - %m - %d %H : %M",
   "%Y - %m - %d",
   "%a %b %d %H : %M : %E*S %Z %Y",
@@ -60,7 +61,7 @@ const char* const kFormats[] = {
 
 bool ParseTimeSpec(const std::string& args, time_point<seconds>* when) {
   const cctz::time_zone ignored{};
-  for (const char* const* fmt = kFormats; *fmt != NULL; ++fmt) {
+  for (const char* const* fmt = kFormats; *fmt != nullptr; ++fmt) {
     const std::string format = std::string(*fmt) + " %E*z";
     time_point<seconds> tp;
     if (cctz::parse(format, args, ignored, &tp)) {
@@ -73,7 +74,7 @@ bool ParseTimeSpec(const std::string& args, time_point<seconds>* when) {
 
 bool ParseCivilSpec(const std::string& args, cctz::civil_second* when) {
   const cctz::time_zone utc = cctz::utc_time_zone();
-  for (const char* const* fmt = kFormats; *fmt != NULL; ++fmt) {
+  for (const char* const* fmt = kFormats; *fmt != nullptr; ++fmt) {
     time_point<seconds> tp;
     if (cctz::parse(*fmt, args, utc, &tp)) {
       *when = cctz::convert(tp, utc);
@@ -101,10 +102,9 @@ std::string FormatTimeInZone(const std::string& fmt, time_point<seconds> when,
   std::ostringstream oss;
   oss << std::setw(36) << std::left << cctz::format(fmt, when, zone);
   cctz::time_zone::absolute_lookup al = zone.lookup(when);
-  cctz::civil_day cd(al.cs);
-  oss << " [wd=" << WeekDayName(cctz::get_weekday(cd))
+  oss << " [wd=" << WeekDayName(cctz::get_weekday(al.cs))
       << " yd=" << std::setw(3) << std::setfill('0')
-      << std::right << cctz::get_yearday(cd)
+      << std::right << cctz::get_yearday(al.cs)
       << " dst=" << (al.is_dst ? 'T' : 'F')
       << " off=" << std::showpos << al.offset << std::noshowpos << "]";
   return oss.str();
@@ -142,7 +142,7 @@ void InstantInfo(const std::string& label, const std::string& fmt,
 }
 
 // Report everything we know about a cctz::civil_second (YMDHMS).
-void CivilInfo(const std::string& fmt, const cctz::civil_second& cs,
+void CivilInfo(const std::string& fmt, const cctz::civil_second cs,
                cctz::time_zone zone) {
   ZoneInfo("tz: ", zone);
   cctz::time_zone::civil_lookup cl = zone.lookup(cs);
@@ -215,7 +215,7 @@ void ZoneDump(bool zdump, const std::string& fmt, cctz::time_zone zone,
         std::cout << " isdst=" << (al.is_dst ? '1' : '0')
                   << " gmtoff=" << al.offset << "\n";
       } else {
-        const char* wd = WeekDayName(get_weekday(cctz::civil_day(al.cs)));
+        const char* wd = WeekDayName(get_weekday(al.cs));
         std::cout << " [wd=" << wd << " dst=" << (al.is_dst ? 'T' : 'F')
                   << " off=" << al.offset << "]\n";
       }
@@ -233,7 +233,7 @@ void ZoneDump(bool zdump, const std::string& fmt, cctz::time_zone zone,
 }
 
 const char* Basename(const char* p) {
-  if (const char* b = strrchr(p, '/')) return ++b;
+  if (const char* b = std::strrchr(p, '/')) return ++b;
   return p;
 }
 
@@ -297,19 +297,19 @@ bool ParseYearRange(bool zdump, const std::string& args,
   return false;
 }
 
-int main(int argc, char** argv) {
+int main(int argc, const char** argv) {
   const char* argv0 = (argc > 0) ? (argc--, *argv++) : (argc = 0, "time_tool");
   const std::string prog = Basename(argv0);
 
   // Escape arguments that look like negative offsets so that they
   // don't look like flags.
+  std::vector<std::string> eargs;
   for (int i = 0; i < argc; ++i) {
-    if (strcmp(argv[i], "--") == 0) break;
+    if (std::strcmp(argv[i], "--") == 0) break;
     if (LooksLikeNegOffset(argv[i])) {
-      char* buf = new char[strlen(argv[i] + 2)];
-      buf[0] = ' ';  // will later be ignorned
-      strcpy(buf + 1, argv[i]);
-      argv[i] = buf;
+      eargs.push_back(" ");  // space will later be ignorned
+      eargs.back().append(argv[i]);
+      argv[i] = eargs.back().c_str();
     }
   }
 
@@ -362,27 +362,27 @@ int main(int argc, char** argv) {
         ++optind;
         break;
       }
-      if (strcmp(opt, "tz") == 0) {
+      if (std::strcmp(opt, "tz") == 0) {
         if (optind + 1 == argc) {
           std::cerr << argv0 << ": option '--tz' requires an argument\n";
           ++opterr;
         } else {
           zones = argv[++optind];
         }
-      } else if (strncmp(opt, "tz=", 3) == 0) {
+      } else if (std::strncmp(opt, "tz=", 3) == 0) {
         zones = opt + 3;
-      } else if (strcmp(opt, "fmt") == 0) {
+      } else if (std::strcmp(opt, "fmt") == 0) {
         if (optind + 1 == argc) {
           std::cerr << argv0 << ": option '--fmt' requires an argument\n";
           ++opterr;
         } else {
           fmt = argv[++optind];
         }
-      } else if (strncmp(opt, "fmt=", 4) == 0) {
+      } else if (std::strncmp(opt, "fmt=", 4) == 0) {
         fmt = opt + 4;
-      } else if (strcmp(opt, "zdump") == 0) {
+      } else if (std::strcmp(opt, "zdump") == 0) {
         zdump = true;
-      } else if (strcmp(opt, "zone_dump") == 0) {
+      } else if (std::strcmp(opt, "zone_dump") == 0) {
         zone_dump = true;
       } else {
         std::cerr << argv0 << ": unrecognized option '--" << opt << "'\n";
@@ -433,7 +433,9 @@ int main(int argc, char** argv) {
   for (const std::string& tz : StrSplit(',', zones)) {
     std::cout << leader;
     cctz::time_zone zone;
-    if (!cctz::load_time_zone(tz, &zone)) {
+    if (tz == "localtime") {
+      zone = cctz::local_time_zone();
+    } else if (!cctz::load_time_zone(tz, &zone)) {
       std::cerr << tz << ": Unrecognized time zone\n";
       return 1;
     }
diff --git a/src/time_zone_fixed.cc b/src/time_zone_fixed.cc
index 9da22c6..6031d7c 100644
--- a/src/time_zone_fixed.cc
+++ b/src/time_zone_fixed.cc
@@ -25,7 +25,7 @@ namespace cctz {
 namespace {
 
 // The prefix used for the internal names of fixed-offset zones.
-const char kFixedOffsetPrefix[] = "Fixed/UTC";
+const char kFixedZonePrefix[] = "Fixed/UTC";
 
 const char kDigits[] = "0123456789";
 
@@ -48,16 +48,16 @@ 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;
   }
 
-  const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1;
-  const char* const ep = kFixedOffsetPrefix + prefix_len;
+  const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
+  const char* const ep = kFixedZonePrefix + prefix_len;
   if (name.size() != prefix_len + 9)  // <prefix>+99:99:99
     return false;
-  if (!std::equal(kFixedOffsetPrefix, ep, name.begin()))
+  if (!std::equal(kFixedZonePrefix, ep, name.begin()))
     return false;
   const char* np = name.data() + prefix_len;
   if (np[0] != '+' && np[0] != '-')
@@ -86,29 +86,29 @@ std::string FixedOffsetToName(const seconds& offset) {
     // offsets and to (somewhat) limit the total number of zones.
     return "UTC";
   }
-  int seconds = static_cast<int>(offset.count());
-  const char sign = (seconds < 0 ? '-' : '+');
-  int minutes = seconds / 60;
-  seconds %= 60;
+  int offset_seconds = static_cast<int>(offset.count());
+  const char sign = (offset_seconds < 0 ? '-' : '+');
+  int offset_minutes = offset_seconds / 60;
+  offset_seconds %= 60;
   if (sign == '-') {
-    if (seconds > 0) {
-      seconds -= 60;
-      minutes += 1;
+    if (offset_seconds > 0) {
+      offset_seconds -= 60;
+      offset_minutes += 1;
     }
-    seconds = -seconds;
-    minutes = -minutes;
+    offset_seconds = -offset_seconds;
+    offset_minutes = -offset_minutes;
   }
-  int hours = minutes / 60;
-  minutes %= 60;
-  char buf[sizeof(kFixedOffsetPrefix) - 1 + sizeof("-24:00:00")];
-  std::strcpy(buf, kFixedOffsetPrefix);
-  char* ep = buf + sizeof(kFixedOffsetPrefix) - 1;
+  int offset_hours = offset_minutes / 60;
+  offset_minutes %= 60;
+  const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
+  char buf[prefix_len + sizeof("-24:00:00")];
+  char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf);
   *ep++ = sign;
-  ep = Format02d(ep, hours);
+  ep = Format02d(ep, offset_hours);
   *ep++ = ':';
-  ep = Format02d(ep, minutes);
+  ep = Format02d(ep, offset_minutes);
   *ep++ = ':';
-  ep = Format02d(ep, seconds);
+  ep = Format02d(ep, offset_seconds);
   *ep++ = '\0';
   assert(ep == buf + sizeof(buf));
   return buf;
@@ -116,7 +116,7 @@ std::string FixedOffsetToName(const seconds& offset) {
 
 std::string FixedOffsetToAbbr(const seconds& offset) {
   std::string abbr = FixedOffsetToName(offset);
-  const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1;
+  const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1;
   if (abbr.size() == prefix_len + 9) {         // <prefix>+99:99:99
     abbr.erase(0, prefix_len);                 // +99:99:99
     abbr.erase(6, 1);                          // +99:9999
diff --git a/src/time_zone_format.cc b/src/time_zone_format.cc
index a12367e..b573713 100644
--- a/src/time_zone_format.cc
+++ b/src/time_zone_format.cc
@@ -18,8 +18,18 @@
 # endif
 #endif
 
+#if defined(HAS_STRPTIME) && HAS_STRPTIME
+# if !defined(_XOPEN_SOURCE)
+#  define _XOPEN_SOURCE  // Definedness suffices for strptime.
+# endif
+#endif
+
 #include "cctz/time_zone.h"
 
+// Include time.h directly since, by C++ standards, ctime doesn't have to
+// declare strptime.
+#include <time.h>
+
 #include <cctype>
 #include <chrono>
 #include <cstddef>
@@ -53,6 +63,48 @@ char* strptime(const char* s, const char* fmt, std::tm* tm) {
 }
 #endif
 
+// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0).
+int ToTmWday(weekday wd) {
+  switch (wd) {
+    case weekday::sunday:
+      return 0;
+    case weekday::monday:
+      return 1;
+    case weekday::tuesday:
+      return 2;
+    case weekday::wednesday:
+      return 3;
+    case weekday::thursday:
+      return 4;
+    case weekday::friday:
+      return 5;
+    case weekday::saturday:
+      return 6;
+  }
+  return 0; /*NOTREACHED*/
+}
+
+// Convert a tm_wday value (0-6, Sunday = 0) to a cctz::weekday.
+weekday FromTmWday(int tm_wday) {
+  switch (tm_wday) {
+    case 0:
+      return weekday::sunday;
+    case 1:
+      return weekday::monday;
+    case 2:
+      return weekday::tuesday;
+    case 3:
+      return weekday::wednesday;
+    case 4:
+      return weekday::thursday;
+    case 5:
+      return weekday::friday;
+    case 6:
+      return weekday::saturday;
+  }
+  return weekday::sunday; /*NOTREACHED*/
+}
+
 std::tm ToTM(const time_zone::absolute_lookup& al) {
   std::tm tm{};
   tm.tm_sec = al.cs.second();
@@ -70,34 +122,19 @@ std::tm ToTM(const time_zone::absolute_lookup& al) {
     tm.tm_year = static_cast<int>(al.cs.year() - 1900);
   }
 
-  switch (get_weekday(civil_day(al.cs))) {
-    case weekday::sunday:
-      tm.tm_wday = 0;
-      break;
-    case weekday::monday:
-      tm.tm_wday = 1;
-      break;
-    case weekday::tuesday:
-      tm.tm_wday = 2;
-      break;
-    case weekday::wednesday:
-      tm.tm_wday = 3;
-      break;
-    case weekday::thursday:
-      tm.tm_wday = 4;
-      break;
-    case weekday::friday:
-      tm.tm_wday = 5;
-      break;
-    case weekday::saturday:
-      tm.tm_wday = 6;
-      break;
-  }
-  tm.tm_yday = get_yearday(civil_day(al.cs)) - 1;
+  tm.tm_wday = ToTmWday(get_weekday(al.cs));
+  tm.tm_yday = get_yearday(al.cs) - 1;
   tm.tm_isdst = al.is_dst ? 1 : 0;
   return tm;
 }
 
+// Returns the week of the year [0:53] given a civil day and the day on
+// which weeks are defined to start.
+int ToWeek(const civil_day& cd, weekday week_start) {
+  const civil_day d(cd.year() % 400, cd.month(), cd.day());
+  return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7);
+}
+
 const char kDigits[] = "0123456789";
 
 // Formats a 64-bit integer in the given field width.  Note that it is up
@@ -276,6 +313,7 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = {
 //   - %E#S - Seconds with # digits of fractional precision
 //   - %E*S - Seconds with full fractional precision (a literal '*')
 //   - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999)
+//   - %ET  - The RFC3339 "date-time" separator "T"
 //
 // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
 // handled internally for performance reasons.  strftime(3) is slow due to
@@ -340,7 +378,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
     if (cur == end || (cur - percent) % 2 == 0) continue;
 
     // Simple specifiers that we handle ourselves.
-    if (strchr("YmdeHMSzZs%", *cur)) {
+    if (strchr("YmdeUuWwHMSzZs%", *cur)) {
       if (cur - 1 != pending) {
         FormatTM(&result, std::string(pending, cur - 1), tm);
       }
@@ -361,6 +399,22 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
           if (*cur == 'e' && *bp == '0') *bp = ' ';  // for Windows
           result.append(bp, static_cast<std::size_t>(ep - bp));
           break;
+        case 'U':
+          bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday));
+          result.append(bp, static_cast<std::size_t>(ep - bp));
+          break;
+        case 'u':
+          bp = Format64(ep, 0, tm.tm_wday ? tm.tm_wday : 7);
+          result.append(bp, static_cast<std::size_t>(ep - bp));
+          break;
+        case 'W':
+          bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::monday));
+          result.append(bp, static_cast<std::size_t>(ep - bp));
+          break;
+        case 'w':
+          bp = Format64(ep, 0, tm.tm_wday);
+          result.append(bp, static_cast<std::size_t>(ep - bp));
+          break;
         case 'H':
           bp = Format02d(ep, al.cs.hour());
           result.append(bp, static_cast<std::size_t>(ep - bp));
@@ -434,7 +488,14 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
     if (*cur != 'E' || ++cur == end) continue;
 
     // Format our extensions.
-    if (*cur == 'z') {
+    if (*cur == 'T') {
+      // Formats %ET.
+      if (cur - 2 != pending) {
+        FormatTM(&result, std::string(pending, cur - 2), tm);
+      }
+      result.append("T");
+      pending = ++cur;
+    } else if (*cur == 'z') {
       // Formats %Ez.
       if (cur - 2 != pending) {
         FormatTM(&result, std::string(pending, cur - 2), tm);
@@ -536,7 +597,7 @@ const char* ParseOffset(const char* dp, const char* mode, int* offset) {
       } else {
         dp = nullptr;
       }
-    } else if (first == 'Z') {  // Zulu
+    } else if (first == 'Z' || first == 'z') {  // Zulu
       *offset = 0;
     } else {
       dp = nullptr;
@@ -587,12 +648,32 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
   return dp;
 }
 
+// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday,
+// and the day on which weeks are defined to start.  Returns false if year
+// would need to move outside its bounds.
+bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) {
+  const civil_year y(*year % 400);
+  civil_day cd = prev_weekday(y, week_start);  // week 0
+  cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7);
+  if (const year_t shift = cd.year() - y.year()) {
+    if (shift > 0) {
+      if (*year > std::numeric_limits<year_t>::max() - shift) return false;
+    } else {
+      if (*year < std::numeric_limits<year_t>::min() - shift) return false;
+    }
+    *year += shift;
+  }
+  tm->tm_mon = cd.month() - 1;
+  tm->tm_mday = cd.day();
+  return true;
+}
+
 }  // namespace
 
 // Uses strptime(3) to parse the given input.  Supports the same extended
 // format specifiers as format(), although %E#S and %E*S are treated
 // identically (and similarly for %E#f and %E*f).  %Ez and %E*z also accept
-// the same inputs.
+// the same inputs. %ET accepts either 'T' or 't'.
 //
 // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are
 // handled internally so that we can normally avoid strptime() altogether
@@ -636,6 +717,8 @@ bool parse(const std::string& format, const std::string& input,
   const char* fmt = format.c_str();  // NUL terminated
   bool twelve_hour = false;
   bool afternoon = false;
+  int week_num = -1;
+  weekday week_start = weekday::sunday;
 
   bool saw_percent_s = false;
   std::int_fast64_t percent_s = 0;
@@ -674,10 +757,27 @@ bool parse(const std::string& format, const std::string& input,
       case 'm':
         data = ParseInt(data, 2, 1, 12, &tm.tm_mon);
         if (data != nullptr) tm.tm_mon -= 1;
+        week_num = -1;
         continue;
       case 'd':
       case 'e':
         data = ParseInt(data, 2, 1, 31, &tm.tm_mday);
+        week_num = -1;
+        continue;
+      case 'U':
+        data = ParseInt(data, 0, 0, 53, &week_num);
+        week_start = weekday::sunday;
+        continue;
+      case 'W':
+        data = ParseInt(data, 0, 0, 53, &week_num);
+        week_start = weekday::monday;
+        continue;
+      case 'u':
+        data = ParseInt(data, 0, 1, 7, &tm.tm_wday);
+        if (data != nullptr) tm.tm_wday %= 7;
+        continue;
+      case 'w':
+        data = ParseInt(data, 0, 0, 6, &tm.tm_wday);
         continue;
       case 'H':
         data = ParseInt(data, 2, 0, 23, &tm.tm_hour);
@@ -728,6 +828,15 @@ bool parse(const std::string& format, const std::string& input,
         data = (*data == '%' ? data + 1 : nullptr);
         continue;
       case 'E':
+        if (fmt[0] == 'T') {
+          if (*data == 'T' || *data == 't') {
+            ++data;
+            ++fmt;
+          } else {
+            data = nullptr;
+          }
+          continue;
+        }
         if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) {
           data = ParseOffset(data, ":", &offset);
           if (data != nullptr) saw_offset = true;
@@ -860,6 +969,14 @@ bool parse(const std::string& format, const std::string& input,
     year += 1900;
   }
 
+  // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number.
+  if (week_num != -1) {
+    if (!FromWeek(week_num, week_start, &year, &tm)) {
+      if (err != nullptr) *err = "Out-of-range field";
+      return false;
+    }
+  }
+
   const int month = tm.tm_mon + 1;
   civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 
diff --git a/src/time_zone_format_test.cc b/src/time_zone_format_test.cc
index ad611cf..41c3dda 100644
--- a/src/time_zone_format_test.cc
+++ b/src/time_zone_format_test.cc
@@ -15,6 +15,7 @@
 #include "cctz/time_zone.h"
 
 #include <chrono>
+#include <cstdint>
 #include <iomanip>
 #include <sstream>
 #include <string>
@@ -45,8 +46,8 @@ namespace {
     EXPECT_STREQ(zone, al.abbr);                                  \
   } while (0)
 
-const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez";
-const char RFC3339_sec[] =  "%Y-%m-%dT%H:%M:%S%Ez";
+const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez";
+const char RFC3339_sec[] =  "%Y-%m-%d%ET%H:%M:%S%Ez";
 
 const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z";
 const char RFC1123_no_wday[] =  "%d %b %Y %H:%M:%S %z";
@@ -673,6 +674,34 @@ TEST(Format, RFC1123Format) {  // locale specific
   EXPECT_EQ("28 Jun 1977 09:08:07 -0700", format(RFC1123_no_wday, tp, tz));
 }
 
+TEST(Format, Week) {
+  const time_zone utc = utc_time_zone();
+
+  auto tp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc);
+  EXPECT_EQ("2017-01-7", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2017-00-0", format("%Y-%W-%w", tp, utc));
+
+  tp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc);
+  EXPECT_EQ("2017-53-7", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2017-52-0", format("%Y-%W-%w", tp, utc));
+
+  tp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc);
+  EXPECT_EQ("2018-00-1", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2018-01-1", format("%Y-%W-%w", tp, utc));
+
+  tp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc);
+  EXPECT_EQ("2018-52-1", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2018-53-1", format("%Y-%W-%w", tp, utc));
+
+  tp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc);
+  EXPECT_EQ("2019-00-2", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2019-00-2", format("%Y-%W-%w", tp, utc));
+
+  tp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
+  EXPECT_EQ("2019-52-2", format("%Y-%U-%u", tp, utc));
+  EXPECT_EQ("2019-52-2", format("%Y-%W-%w", tp, utc));
+}
+
 //
 // Testing parse()
 //
@@ -1101,7 +1130,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;
@@ -1183,7 +1212,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);
@@ -1246,9 +1275,9 @@ TEST(Parse, ExtendedSubecondsScan) {
         const auto expected = chrono::system_clock::from_time_t(0) +
                               chrono::nanoseconds(micros * 1000 + ns);
         for (int ps = 0; ps < 1000; ps += 250) {
-          std::ostringstream oss;
+          std::ostringstream ps_oss;
           oss << std::setfill('0') << std::setw(3) << ps;
-          const std::string input = nanos + oss.str() + "999";
+          const std::string input = nanos + ps_oss.str() + "999";
           EXPECT_TRUE(parse("%E*f", input, tz, &tp));
           EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input;
         }
@@ -1373,10 +1402,85 @@ TEST(Parse, RFC3339Format) {
   EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00+00:00", tz, &tp));
   ExpectTime(tp, tz, 2014, 2, 12, 20, 21, 0, 0, false, "UTC");
 
-  // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+  // Check that %ET also accepts "t".
   time_point<chrono::nanoseconds> tp2;
-  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp2));
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12t20:21:00+00:00", tz, &tp2));
   EXPECT_EQ(tp, tp2);
+
+  // Check that %Ez also accepts "Z" as a synonym for "+00:00".
+  time_point<chrono::nanoseconds> tp3;
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00Z", tz, &tp3));
+  EXPECT_EQ(tp, tp3);
+
+  // Check that %Ez also accepts "z" as a synonym for "+00:00".
+  time_point<chrono::nanoseconds> tp4;
+  EXPECT_TRUE(parse(RFC3339_sec, "2014-02-12T20:21:00z", tz, &tp4));
+  EXPECT_EQ(tp, tp4);
+}
+
+TEST(Parse, Week) {
+  const time_zone utc = utc_time_zone();
+  time_point<cctz::seconds> tp;
+
+  auto exp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2017-01-7", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2017-00-0", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2017-53-7", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2017-52-0", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2018-00-1", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2018-01-1", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2018-52-1", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2018-53-1", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2019-00-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2019-00-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2019-52-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2019-52-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+}
+
+TEST(Parse, WeekYearShift) {
+  // %U/%W conversions with week values in {0, 52, 53} can slip
+  // into the previous/following calendar years.
+  const time_zone utc = utc_time_zone();
+  time_point<cctz::seconds> tp;
+
+  auto exp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2020-00-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2020-00-2", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  exp = convert(civil_second(2021, 1, 1, 0, 0, 0), utc);
+  EXPECT_TRUE(parse("%Y-%U-%u", "2020-52-5", utc, &tp));
+  EXPECT_EQ(exp, tp);
+  EXPECT_TRUE(parse("%Y-%W-%w", "2020-52-5", utc, &tp));
+  EXPECT_EQ(exp, tp);
+
+  // Slipping into the previous/following calendar years should fail when
+  // we're already at the extremes.
+  EXPECT_FALSE(parse("%Y-%U-%u", "-9223372036854775808-0-7", utc, &tp));
+  EXPECT_FALSE(parse("%Y-%U-%u", "9223372036854775807-53-7", utc, &tp));
 }
 
 TEST(Parse, MaxRange) {
@@ -1395,7 +1499,7 @@ TEST(Parse, MaxRange) {
       parse(RFC3339_sec, "292277026596-12-04T14:30:07-01:00", utc, &tp));
   EXPECT_EQ(tp, time_point<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(
@@ -1416,10 +1520,82 @@ TEST(Parse, MaxRange) {
                      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();
 
-  // 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.
+  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));
+}
+
+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/src/time_zone_if.h b/src/time_zone_if.h
index f925c6c..8e27087 100644
--- a/src/time_zone_if.h
+++ b/src/time_zone_if.h
@@ -53,7 +53,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))).count();
diff --git a/src/time_zone_impl.cc b/src/time_zone_impl.cc
index 3064155..6e07750 100644
--- a/src/time_zone_impl.cc
+++ b/src/time_zone_impl.cc
@@ -14,6 +14,8 @@
 
 #include "time_zone_impl.h"
 
+#include <deque>
+#include <memory>
 #include <mutex>
 #include <string>
 #include <unordered_map>
@@ -31,7 +33,12 @@ using TimeZoneImplByName =
 TimeZoneImplByName* time_zone_map = nullptr;
 
 // Mutual exclusion for time_zone_map.
-std::mutex time_zone_mutex;
+std::mutex& TimeZoneMutex() {
+  // This mutex is intentionally "leaked" to avoid the static deinitialization
+  // order fiasco (std::mutex's destructor is not trivial on many platforms).
+  static std::mutex* time_zone_mutex = new std::mutex;
+  return *time_zone_mutex;
+}
 
 }  // namespace
 
@@ -40,19 +47,18 @@ time_zone time_zone::Impl::UTC() {
 }
 
 bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) {
-  const time_zone::Impl* const utc_impl = UTCImpl();
+  const Impl* const utc_impl = UTCImpl();
 
-  // First check for UTC (which is never a key in time_zone_map).
+  // Check for UTC (which is never a key in time_zone_map).
   auto offset = seconds::zero();
   if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) {
     *tz = time_zone(utc_impl);
     return true;
   }
 
-  // Then check, under a shared lock, whether the time zone has already
-  // been loaded. This is the common path. TODO: Move to shared_mutex.
+  // Check whether the time zone has already been loaded.
   {
-    std::lock_guard<std::mutex> lock(time_zone_mutex);
+    std::lock_guard<std::mutex> lock(TimeZoneMutex());
     if (time_zone_map != nullptr) {
       TimeZoneImplByName::const_iterator itr = time_zone_map->find(name);
       if (itr != time_zone_map->end()) {
@@ -62,42 +68,40 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) {
     }
   }
 
-  // Now check again, under an exclusive lock.
-  std::lock_guard<std::mutex> lock(time_zone_mutex);
+  // Load the new time zone (outside the lock).
+  std::unique_ptr<const Impl> new_impl(new Impl(name));
+
+  // Add the new time zone to the map.
+  std::lock_guard<std::mutex> lock(TimeZoneMutex());
   if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName;
   const Impl*& impl = (*time_zone_map)[name];
-  if (impl == nullptr) {
-    // The first thread in loads the new time zone.
-    Impl* new_impl = new Impl(name);
-    new_impl->zone_ = TimeZoneIf::Load(new_impl->name_);
-    if (new_impl->zone_ == nullptr) {
-      delete new_impl;  // free the nascent Impl
-      impl = utc_impl;  // and fallback to UTC
-    } else {
-      impl = new_impl;  // install new time zone
-    }
+  if (impl == nullptr) {  // this thread won any load race
+    impl = new_impl->zone_ ? new_impl.release() : utc_impl;
   }
   *tz = time_zone(impl);
   return impl != utc_impl;
 }
 
 void time_zone::Impl::ClearTimeZoneMapTestOnly() {
-  std::lock_guard<std::mutex> lock(time_zone_mutex);
+  std::lock_guard<std::mutex> lock(TimeZoneMutex());
   if (time_zone_map != nullptr) {
-    // Existing time_zone::Impl* entries are in the wild, so we simply
-    // leak them.  Future requests will result in reloading the data.
+    // Existing time_zone::Impl* entries are in the wild, so we can't delete
+    // them. Instead, we move them to a private container, where they are
+    // logically unreachable but not "leaked".  Future requests will result
+    // in reloading the data.
+    static auto* cleared = new std::deque<const time_zone::Impl*>;
+    for (const auto& element : *time_zone_map) {
+      cleared->push_back(element.second);
+    }
     time_zone_map->clear();
   }
 }
 
-time_zone::Impl::Impl(const std::string& name) : name_(name) {}
+time_zone::Impl::Impl(const std::string& name)
+    : name_(name), zone_(TimeZoneIf::Load(name_)) {}
 
 const time_zone::Impl* time_zone::Impl::UTCImpl() {
-  static Impl* utc_impl = [] {
-    Impl* impl = new Impl("UTC");
-    impl->zone_ = TimeZoneIf::Load(impl->name_);  // never fails
-    return impl;
-  }();
+  static const Impl* utc_impl = new Impl("UTC");  // never fails
   return utc_impl;
 }
 
diff --git a/src/time_zone_info.cc b/src/time_zone_info.cc
index eb1cd8a..77a9073 100644
--- a/src/time_zone_info.cc
+++ b/src/time_zone_info.cc
@@ -39,11 +39,12 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
+#include <fstream>
 #include <functional>
-#include <iostream>
 #include <memory>
 #include <sstream>
 #include <string>
+#include <utility>
 
 #include "cctz/civil_time.h"
 #include "time_zone_fixed.h"
@@ -79,6 +80,27 @@ const std::int_least32_t kSecsPerYear[2] = {
   366 * kSecsPerDay,
 };
 
+// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat).
+inline int ToPosixWeekday(weekday wd) {
+  switch (wd) {
+    case weekday::sunday:
+      return 0;
+    case weekday::monday:
+      return 1;
+    case weekday::tuesday:
+      return 2;
+    case weekday::wednesday:
+      return 3;
+    case weekday::thursday:
+      return 4;
+    case weekday::friday:
+      return 5;
+    case weekday::saturday:
+      return 6;
+  }
+  return 0; /*NOTREACHED*/
+}
+
 // Single-byte, unsigned numeric values are encoded directly.
 inline std::uint_fast8_t Decode8(const char* cp) {
   return static_cast<std::uint_fast8_t>(*cp) & 0xff;
@@ -184,15 +206,13 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) {
   tt.is_dst = false;
   tt.abbr_index = 0;
 
-  // We temporarily add some redundant, contemporary (2013 through 2023)
+  // We temporarily add some redundant, contemporary (2015 through 2025)
   // transitions for performance reasons.  See TimeZoneInfo::LocalTime().
   // TODO: Fix the performance issue and remove the extra transitions.
   transitions_.clear();
   transitions_.reserve(12);
   for (const std::int_fast64_t unix_time : {
-           -(1LL << 59),  // BIG_BANG
-           1356998400LL,  // 2013-01-01T00:00:00+00:00
-           1388534400LL,  // 2014-01-01T00:00:00+00:00
+           -(1LL << 59),  // a "first half" transition
            1420070400LL,  // 2015-01-01T00:00:00+00:00
            1451606400LL,  // 2016-01-01T00:00:00+00:00
            1483228800LL,  // 2017-01-01T00:00:00+00:00
@@ -202,7 +222,8 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) {
            1609459200LL,  // 2021-01-01T00:00:00+00:00
            1640995200LL,  // 2022-01-01T00:00:00+00:00
            1672531200LL,  // 2023-01-01T00:00:00+00:00
-           2147483647LL,  // 2^31 - 1
+           1704067200LL,  // 2024-01-01T00:00:00+00:00
+           1735689600LL,  // 2025-01-01T00:00:00+00:00
        }) {
     Transition& tr(*transitions_.emplace(transitions_.end()));
     tr.unix_time = unix_time;
@@ -213,7 +234,7 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) {
 
   default_transition_type_ = 0;
   abbreviations_ = FixedOffsetToAbbr(offset);
-  abbreviations_.append(1, '\0');  // add NUL
+  abbreviations_.append(1, '\0');
   future_spec_.clear();  // never needed for a fixed-offset zone
   extended_ = false;
 
@@ -237,8 +258,8 @@ bool TimeZoneInfo::Header::Build(const tzhead& tzh) {
   leapcnt = static_cast<std::size_t>(v);
   if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false;
   ttisstdcnt = static_cast<std::size_t>(v);
-  if ((v = Decode32(tzh.tzh_ttisgmtcnt)) < 0) return false;
-  ttisgmtcnt = static_cast<std::size_t>(v);
+  if ((v = Decode32(tzh.tzh_ttisutcnt)) < 0) return false;
+  ttisutcnt = static_cast<std::size_t>(v);
   return true;
 }
 
@@ -251,25 +272,10 @@ std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const {
   len += 1 * charcnt;               // abbreviations
   len += (time_len + 4) * leapcnt;  // leap-time + TAI-UTC
   len += 1 * ttisstdcnt;            // UTC/local indicators
-  len += 1 * ttisgmtcnt;            // standard/wall indicators
+  len += 1 * ttisutcnt;             // standard/wall indicators
   return len;
 }
 
-// Check that the TransitionType has the expected offset/is_dst/abbreviation.
-void TimeZoneInfo::CheckTransition(const std::string& name,
-                                   const TransitionType& tt,
-                                   std::int_fast32_t offset, bool is_dst,
-                                   const std::string& abbr) const {
-  if (tt.utc_offset != offset || tt.is_dst != is_dst ||
-      &abbreviations_[tt.abbr_index] != abbr) {
-    std::clog << name << ": Transition"
-              << " offset=" << tt.utc_offset << "/"
-              << (tt.is_dst ? "DST" : "STD")
-              << "/abbr=" << &abbreviations_[tt.abbr_index]
-              << " does not match POSIX spec '" << future_spec_ << "'\n";
-  }
-}
-
 // zic(8) can generate no-op transitions when a zone changes rules at an
 // instant when there is actually no discontinuity.  So we check whether
 // two transitions have equivalent types (same offset/is_dst/abbr).
@@ -278,117 +284,108 @@ bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index,
   if (tt1_index == tt2_index) return true;
   const TransitionType& tt1(transition_types_[tt1_index]);
   const TransitionType& tt2(transition_types_[tt2_index]);
-  if (tt1.is_dst != tt2.is_dst) return false;
   if (tt1.utc_offset != tt2.utc_offset) return false;
+  if (tt1.is_dst != tt2.is_dst) return false;
   if (tt1.abbr_index != tt2.abbr_index) return false;
   return true;
 }
 
+// Find/make a transition type with these attributes.
+bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
+                                     const std::string& abbr,
+                                     std::uint_least8_t* index) {
+  std::size_t type_index = 0;
+  std::size_t abbr_index = abbreviations_.size();
+  for (; type_index != transition_types_.size(); ++type_index) {
+    const TransitionType& tt(transition_types_[type_index]);
+    const char* tt_abbr = &abbreviations_[tt.abbr_index];
+    if (tt_abbr == abbr) abbr_index = tt.abbr_index;
+    if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) {
+      if (abbr_index == tt.abbr_index) break;  // reuse
+    }
+  }
+  if (type_index > 255 || abbr_index > 255) {
+    // No index space (8 bits) available for a new type or abbreviation.
+    return false;
+  }
+  if (type_index == transition_types_.size()) {
+    TransitionType& tt(*transition_types_.emplace(transition_types_.end()));
+    tt.utc_offset = static_cast<std::int_least32_t>(utc_offset);
+    tt.is_dst = is_dst;
+    if (abbr_index == abbreviations_.size()) {
+      abbreviations_.append(abbr);
+      abbreviations_.append(1, '\0');
+    }
+    tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index);
+  }
+  *index = static_cast<std::uint_least8_t>(type_index);
+  return true;
+}
+
 // Use the POSIX-TZ-environment-variable-style string to handle times
 // in years after the last transition stored in the zoneinfo data.
-void TimeZoneInfo::ExtendTransitions(const std::string& name,
-                                     const Header& hdr) {
+bool TimeZoneInfo::ExtendTransitions() {
   extended_ = false;
-  bool extending = !future_spec_.empty();
+  if (future_spec_.empty()) return true;  // last transition prevails
 
   PosixTimeZone posix;
-  if (extending && !ParsePosixSpec(future_spec_, &posix)) {
-    std::clog << name << ": Failed to parse '" << future_spec_ << "'\n";
-    extending = false;
-  }
-
-  if (extending && posix.dst_abbr.empty()) {  // std only
-    // The future specification should match the last/default transition,
-    // and that means that handling the future will fall out naturally.
-    std::uint_fast8_t index = default_transition_type_;
-    if (hdr.timecnt != 0) index = transitions_[hdr.timecnt - 1].type_index;
-    const TransitionType& tt(transition_types_[index]);
-    CheckTransition(name, tt, posix.std_offset, false, posix.std_abbr);
-    extending = false;
-  }
-
-  if (extending && hdr.timecnt < 2) {
-    std::clog << name << ": Too few transitions for POSIX spec\n";
-    extending = false;
-  }
-
-  if (!extending) {
-    // Ensure that there is always a transition in the second half of the
-    // time line (the BIG_BANG transition is in the first half) so that the
-    // signed difference between a civil_second and the civil_second of its
-    // previous transition is always representable, without overflow.
-    const Transition& last(transitions_.back());
-    if (last.unix_time < 0) {
-      const std::uint_fast8_t type_index = last.type_index;
-      Transition& tr(*transitions_.emplace(transitions_.end()));
-      tr.unix_time = 2147483647;  // 2038-01-19T03:14:07+00:00
-      tr.type_index = type_index;
-    }
-    return;  // last transition wins
+  if (!ParsePosixSpec(future_spec_, &posix)) return false;
+
+  // Find transition type for the future std specification.
+  std::uint_least8_t std_ti;
+  if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti))
+    return false;
+
+  if (posix.dst_abbr.empty()) {  // std only
+    // The future specification should match the last transition, and
+    // that means that handling the future will fall out naturally.
+    return EquivTransitions(transitions_.back().type_index, std_ti);
   }
 
+  // Find transition type for the future dst specification.
+  std::uint_least8_t dst_ti;
+  if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti))
+    return false;
+
   // Extend the transitions for an additional 400 years using the
   // future specification. Years beyond those can be handled by
   // mapping back to a cycle-equivalent year within that range.
-  // zic(8) should probably do this so that we don't have to.
-  // TODO: Reduce the extension by the number of compatible
-  // transitions already in place.
-  transitions_.reserve(hdr.timecnt + 400 * 2 + 1);
-  transitions_.resize(hdr.timecnt + 400 * 2);
+  // We may need two additional transitions for the current year.
+  transitions_.reserve(transitions_.size() + 400 * 2 + 2);
   extended_ = true;
 
-  // The future specification should match the last two transitions,
-  // and those transitions should have different is_dst flags.  Note
-  // that nothing says the UTC offset used by the is_dst transition
-  // must be greater than that used by the !is_dst transition.  (See
-  // Europe/Dublin, for example.)
-  const Transition* tr0 = &transitions_[hdr.timecnt - 1];
-  const Transition* tr1 = &transitions_[hdr.timecnt - 2];
-  const TransitionType* tt0 = &transition_types_[tr0->type_index];
-  const TransitionType* tt1 = &transition_types_[tr1->type_index];
-  const TransitionType& dst(tt0->is_dst ? *tt0 : *tt1);
-  const TransitionType& std(tt0->is_dst ? *tt1 : *tt0);
-  CheckTransition(name, dst, posix.dst_offset, true, posix.dst_abbr);
-  CheckTransition(name, std, posix.std_offset, false, posix.std_abbr);
-
-  // Add the transitions to tr1 and back to tr0 for each extra year.
-  last_year_ = LocalTime(tr0->unix_time, *tt0).cs.year();
+  const Transition& last(transitions_.back());
+  const std::int_fast64_t last_time = last.unix_time;
+  const TransitionType& last_tt(transition_types_[last.type_index]);
+  last_year_ = LocalTime(last_time, last_tt).cs.year();
   bool leap_year = IsLeap(last_year_);
-  const civil_day jan1(last_year_, 1, 1);
-  std::int_fast64_t jan1_time = civil_second(jan1) - civil_second();
-  int jan1_weekday = (static_cast<int>(get_weekday(jan1)) + 1) % 7;
-  Transition* tr = &transitions_[hdr.timecnt];  // next trans to fill
-  if (LocalTime(tr1->unix_time, *tt1).cs.year() != last_year_) {
-    // Add a single extra transition to align to a calendar year.
-    transitions_.resize(transitions_.size() + 1);
-    assert(tr == &transitions_[hdr.timecnt]);  // no reallocation
-    const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start);
-    std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1);
-    tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset;
-    tr++->type_index = tr1->type_index;
-    tr0 = &transitions_[hdr.timecnt];
-    tr1 = &transitions_[hdr.timecnt - 1];
-    tt0 = &transition_types_[tr0->type_index];
-    tt1 = &transition_types_[tr1->type_index];
-  }
-  const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start);
-  const PosixTransition& pt0(tt0->is_dst ? posix.dst_start : posix.dst_end);
-  for (const year_t limit = last_year_ + 400; last_year_ < limit;) {
-    last_year_ += 1;  // an additional year of generated transitions
+  const civil_second jan1(last_year_);
+  std::int_fast64_t jan1_time = jan1 - civil_second();
+  int jan1_weekday = ToPosixWeekday(get_weekday(jan1));
+
+  Transition dst = {0, dst_ti, civil_second(), civil_second()};
+  Transition std = {0, std_ti, civil_second(), civil_second()};
+  for (const year_t limit = last_year_ + 400;; ++last_year_) {
+    auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start);
+    auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end);
+    dst.unix_time = jan1_time + dst_trans_off - posix.std_offset;
+    std.unix_time = jan1_time + std_trans_off - posix.dst_offset;
+    const auto* ta = dst.unix_time < std.unix_time ? &dst : &std;
+    const auto* tb = dst.unix_time < std.unix_time ? &std : &dst;
+    if (last_time < tb->unix_time) {
+      if (last_time < ta->unix_time) transitions_.push_back(*ta);
+      transitions_.push_back(*tb);
+    }
+    if (last_year_ == limit) break;
     jan1_time += kSecsPerYear[leap_year];
     jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7;
-    leap_year = !leap_year && IsLeap(last_year_);
-    std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1);
-    tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset;
-    tr++->type_index = tr1->type_index;
-    std::int_fast64_t tr0_offset = TransOffset(leap_year, jan1_weekday, pt0);
-    tr->unix_time = jan1_time + tr0_offset - tt1->utc_offset;
-    tr++->type_index = tr0->type_index;
+    leap_year = !leap_year && IsLeap(last_year_ + 1);
   }
-  assert(tr == &transitions_[0] + transitions_.size());
+
+  return true;
 }
 
-bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
+bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
   // Read and validate the header.
   tzhead tzh;
   if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh))
@@ -425,7 +422,7 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   }
   if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt)
     return false;
-  if (hdr.ttisgmtcnt != 0 && hdr.ttisgmtcnt != hdr.typecnt)
+  if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt)
     return false;
 
   // Read the data into a local buffer.
@@ -436,7 +433,7 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   const char* bp = tbuf.data();
 
   // Decode and validate the transitions.
-  transitions_.reserve(hdr.timecnt + 2);  // We might add a couple.
+  transitions_.reserve(hdr.timecnt + 2);
   transitions_.resize(hdr.timecnt);
   for (std::size_t i = 0; i != hdr.timecnt; ++i) {
     transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp);
@@ -457,6 +454,7 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   }
 
   // Decode and validate the transition types.
+  transition_types_.reserve(hdr.typecnt + 2);
   transition_types_.resize(hdr.typecnt);
   for (std::size_t i = 0; i != hdr.typecnt; ++i) {
     transition_types_[i].utc_offset =
@@ -487,6 +485,7 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   }
 
   // Copy all the abbreviations.
+  abbreviations_.reserve(hdr.charcnt + 10);
   abbreviations_.assign(bp, hdr.charcnt);
   bp += hdr.charcnt;
 
@@ -496,16 +495,16 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   // that isn't the case here (see "zic -p").
   bp += (8 + 4) * hdr.leapcnt;  // leap-time + TAI-UTC
   bp += 1 * hdr.ttisstdcnt;     // UTC/local indicators
-  bp += 1 * hdr.ttisgmtcnt;     // standard/wall indicators
+  bp += 1 * hdr.ttisutcnt;      // standard/wall indicators
   assert(bp == tbuf.data() + tbuf.size());
 
   future_spec_.clear();
   if (tzh.tzh_version[0] != '\0') {
     // Snarf up the NL-enclosed future POSIX spec. Note
     // that version '3' files utilize an extended format.
-    auto get_char = [](ZoneInfoSource* zip) -> int {
+    auto get_char = [](ZoneInfoSource* azip) -> int {
       unsigned char ch;  // all non-EOF results are positive
-      return (zip->Read(&ch, 1) == 1) ? ch : EOF;
+      return (azip->Read(&ch, 1) == 1) ? ch : EOF;
     };
     if (get_char(zip) != '\n')
       return false;
@@ -539,19 +538,29 @@ bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) {
   transitions_.resize(hdr.timecnt);
 
   // Ensure that there is always a transition in the first half of the
-  // time line (the second half is handled in ExtendTransitions()) so that
-  // the signed difference between a civil_second and the civil_second of
-  // its previous transition is always representable, without overflow.
-  // A contemporary zic will usually have already done this for us.
+  // time line (the second half is handled below) so that the signed
+  // difference between a civil_second and the civil_second of its
+  // previous transition is always representable, without overflow.
   if (transitions_.empty() || transitions_.front().unix_time >= 0) {
     Transition& tr(*transitions_.emplace(transitions_.begin()));
-    tr.unix_time = -(1LL << 59);  // see tz/zic.c "BIG_BANG"
+    tr.unix_time = -(1LL << 59);  // -18267312070-10-26T17:01:52+00:00
     tr.type_index = default_transition_type_;
-    hdr.timecnt += 1;
   }
 
   // Extend the transitions using the future specification.
-  ExtendTransitions(name, hdr);
+  if (!ExtendTransitions()) return false;
+
+  // Ensure that there is always a transition in the second half of the
+  // time line (the first half is handled above) so that the signed
+  // difference between a civil_second and the civil_second of its
+  // previous transition is always representable, without overflow.
+  const Transition& last(transitions_.back());
+  if (last.unix_time < 0) {
+    const std::uint_fast8_t type_index = last.type_index;
+    Transition& tr(*transitions_.emplace(transitions_.end()));
+    tr.unix_time = 2147483647;  // 2038-01-19T03:14:07+00:00
+    tr.type_index = type_index;
+  }
 
   // Compute the local civil time for each transition and the preceding
   // second. These will be used for reverse conversions in MakeTime().
@@ -583,14 +592,17 @@ bool TimeZoneInfo::Load(const std::string& name, 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
 }
 
@@ -618,22 +630,22 @@ 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_;
 };
 
 std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
     const std::string& name) {
   // Use of the "file:" prefix is intended for testing purposes only.
-  if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5));
+  const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
 
   // Map the time-zone name to a path name.
   std::string path;
-  if (name.empty() || name[0] != '/') {
+  if (pos == name.size() || name[pos] != '/') {
     const char* tzdir = "/usr/share/zoneinfo";
     char* tzdir_env = nullptr;
 #if defined(_MSC_VER)
@@ -648,20 +660,12 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
     free(tzdir_env);
 #endif
   }
-  path += name;
+  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 pos = ftell(fp);
-    if (pos >= 0) {
-      length = static_cast<std::size_t>(pos);
-    }
-    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 {
@@ -670,22 +674,22 @@ 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_;
 };
 
 std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
     const std::string& name) {
   // Use of the "file:" prefix is intended for testing purposes only.
-  if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5));
+  const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
 
-#if defined(__ANDROID__)
   // 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;
@@ -708,14 +712,76 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
       const std::int_fast32_t length = Decode32(ebuf + 44);
       if (start < 0 || length < 0) break;
       ebuf[40] = '\0';  // ensure zone name is NUL terminated
-      if (strcmp(name.c_str(), ebuf) == 0) {
+      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));
+      }
+    }
+  }
+
+  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)));
   }
-#endif  // __ANDROID__
+
   return nullptr;
 }
 
@@ -733,12 +799,13 @@ bool TimeZoneInfo::Load(const std::string& name) {
 
   // Find and use a ZoneInfoSource to load the named zone.
   auto zip = cctz_extension::zone_info_source_factory(
-      name, [](const std::string& name) -> std::unique_ptr<ZoneInfoSource> {
-        if (auto zip = FileZoneInfoSource::Open(name)) return zip;
-        if (auto zip = AndroidZoneInfoSource::Open(name)) return zip;
+      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(name, zip.get());
+  return zip != nullptr && Load(zip.get());
 }
 
 // BreakTime() translation for a particular transition type.
@@ -914,8 +981,8 @@ bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp,
   const Transition* begin = &transitions_[0];
   const Transition* end = begin + transitions_.size();
   if (begin->unix_time <= -(1LL << 59)) {
-    // Do not report the BIG_BANG found in recent zoneinfo data as it is
-    // really a sentinel, not a transition.  See tz/zic.c.
+    // Do not report the BIG_BANG found in some zoneinfo data as it is
+    // really a sentinel, not a transition.  See pre-2018f tz/zic.c.
     ++begin;
   }
   std::int_fast64_t unix_time = ToUnixSeconds(tp);
@@ -940,8 +1007,8 @@ bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp,
   const Transition* begin = &transitions_[0];
   const Transition* end = begin + transitions_.size();
   if (begin->unix_time <= -(1LL << 59)) {
-    // Do not report the BIG_BANG found in recent zoneinfo data as it is
-    // really a sentinel, not a transition.  See tz/zic.c.
+    // Do not report the BIG_BANG found in some zoneinfo data as it is
+    // really a sentinel, not a transition.  See pre-2018f tz/zic.c.
     ++begin;
   }
   std::int_fast64_t unix_time = ToUnixSeconds(tp);
diff --git a/src/time_zone_info.h b/src/time_zone_info.h
index 4657a2d..431dc5b 100644
--- a/src/time_zone_info.h
+++ b/src/time_zone_info.h
@@ -86,21 +86,20 @@ class TimeZoneInfo : public TimeZoneIf {
     std::size_t charcnt;     // zone abbreviation characters
     std::size_t leapcnt;     // leap seconds (we expect none)
     std::size_t ttisstdcnt;  // UTC/local indicators (unused)
-    std::size_t ttisgmtcnt;  // standard/wall indicators (unused)
+    std::size_t ttisutcnt;   // standard/wall indicators (unused)
 
     bool Build(const tzhead& tzh);
     std::size_t DataLength(std::size_t time_len) const;
   };
 
-  void CheckTransition(const std::string& name, const TransitionType& tt,
-                       std::int_fast32_t offset, bool is_dst,
-                       const std::string& abbr) const;
+  bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst,
+                         const std::string& abbr, std::uint_least8_t* index);
   bool EquivTransitions(std::uint_fast8_t tt1_index,
                         std::uint_fast8_t tt2_index) const;
-  void ExtendTransitions(const std::string& name, const Header& hdr);
+  bool ExtendTransitions();
 
   bool ResetToBuiltinUTC(const seconds& offset);
-  bool Load(const std::string& name, ZoneInfoSource* zip);
+  bool Load(ZoneInfoSource* zip);
 
   // Helpers for BreakTime() and MakeTime().
   time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time,
diff --git a/src/time_zone_libc.cc b/src/time_zone_libc.cc
index da89fef..f185b95 100644
--- a/src/time_zone_libc.cc
+++ b/src/time_zone_libc.cc
@@ -21,67 +21,90 @@
 #include <chrono>
 #include <ctime>
 #include <limits>
-#include <tuple>
 #include <utility>
 
 #include "cctz/civil_time.h"
 #include "cctz/time_zone.h"
 
+#if defined(_AIX)
+extern "C" {
+  extern long altzone;
+}
+#endif
+
 namespace cctz {
 
 namespace {
 
-// .first is seconds east of UTC; .second is the time-zone abbreviation.
-using OffsetAbbr = std::pair<int, const char*>;
-
-// Defines a function that can be called as follows:
-//
-//   std::tm tm = ...;
-//   OffsetAbbr off_abbr = get_offset_abbr(tm);
-//
 #if defined(_WIN32) || defined(_WIN64)
 // Uses the globals: '_timezone', '_dstbias' and '_tzname'.
-OffsetAbbr get_offset_abbr(const std::tm& tm) {
+auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + _dstbias) {
   const bool is_dst = tm.tm_isdst > 0;
-  const int off = _timezone + (is_dst ? _dstbias : 0);
-  const char* abbr = _tzname[is_dst];
-  return {off, abbr};
+  return _timezone + (is_dst ? _dstbias : 0);
 }
-#elif defined(__sun)
+auto tm_zone(const std::tm& tm) -> decltype(_tzname[0]) {
+  const bool is_dst = tm.tm_isdst > 0;
+  return _tzname[is_dst];
+}
+#elif defined(__sun) || defined(_AIX)
 // Uses the globals: 'timezone', 'altzone' and 'tzname'.
-OffsetAbbr get_offset_abbr(const std::tm& tm) {
+auto tm_gmtoff(const std::tm& tm) -> decltype(timezone) {
+  const bool is_dst = tm.tm_isdst > 0;
+  return is_dst ? altzone : timezone;
+}
+auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
   const bool is_dst = tm.tm_isdst > 0;
-  const int off = is_dst ? altzone : timezone;
-  const char* abbr = tzname[is_dst];
-  return {off, abbr};
+  return tzname[is_dst];
 }
 #elif defined(__native_client__) || defined(__myriad2__) || \
     defined(__EMSCRIPTEN__)
 // Uses the globals: 'timezone' and 'tzname'.
-OffsetAbbr get_offset_abbr(const std::tm& tm) {
+auto tm_gmtoff(const std::tm& tm) -> decltype(_timezone + 0) {
+  const bool is_dst = tm.tm_isdst > 0;
+  return _timezone + (is_dst ? 60 * 60 : 0);
+}
+auto tm_zone(const std::tm& tm) -> decltype(tzname[0]) {
   const bool is_dst = tm.tm_isdst > 0;
-  const int off = _timezone + (is_dst ? 60 * 60 : 0);
-  const char* abbr = tzname[is_dst];
-  return {off, abbr};
+  return tzname[is_dst];
+}
+#else
+// Adapt to different spellings of the struct std::tm extension fields.
+#if defined(tm_gmtoff)
+auto tm_gmtoff(const std::tm& tm) -> decltype(tm.tm_gmtoff) {
+  return tm.tm_gmtoff;
+}
+#elif defined(__tm_gmtoff)
+auto tm_gmtoff(const std::tm& tm) -> decltype(tm.__tm_gmtoff) {
+  return tm.__tm_gmtoff;
+}
+#else
+template <typename T>
+auto tm_gmtoff(const T& tm) -> decltype(tm.tm_gmtoff) {
+  return tm.tm_gmtoff;
+}
+template <typename T>
+auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) {
+  return tm.__tm_gmtoff;
+}
+#endif  // tm_gmtoff
+#if defined(tm_zone)
+auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) {
+  return tm.tm_zone;
+}
+#elif defined(__tm_zone)
+auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) {
+  return tm.__tm_zone;
 }
 #else
-//
-// Returns an OffsetAbbr using std::tm fields with various spellings.
-//
-#if !defined(tm_gmtoff) && !defined(tm_zone)
 template <typename T>
-OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::tm_gmtoff) = nullptr,
-                           decltype(&T::tm_zone) = nullptr) {
-  return {tm.tm_gmtoff, tm.tm_zone};
+auto tm_zone(const T& tm) -> decltype(tm.tm_zone) {
+  return tm.tm_zone;
 }
-#endif  // !defined(tm_gmtoff) && !defined(tm_zone)
-#if !defined(__tm_gmtoff) && !defined(__tm_zone)
 template <typename T>
-OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr,
-                           decltype(&T::__tm_zone) = nullptr) {
-  return {tm.__tm_gmtoff, tm.__tm_zone};
+auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) {
+  return tm.__tm_zone;
 }
-#endif  // !defined(__tm_gmtoff) && !defined(__tm_zone)
+#endif  // tm_zone
 #endif
 
 inline std::tm* gm_time(const std::time_t *timep, std::tm *result) {
@@ -124,7 +147,7 @@ bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) {
       return false;
     }
   }
-  *off = get_offset_abbr(tm).first;
+  *off = static_cast<int>(tm_gmtoff(tm));
   return true;
 }
 
@@ -134,8 +157,9 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) {
   std::tm tm;
   while (lo + 1 != hi) {
     const std::time_t mid = lo + (hi - lo) / 2;
-    if (std::tm* tmp = local_time(&mid, &tm)) {
-      if (get_offset_abbr(*tmp).first == offset) {
+    std::tm* tmp = local_time(&mid, &tm);
+    if (tmp != nullptr) {
+      if (tm_gmtoff(*tmp) == offset) {
         hi = mid;
       } else {
         lo = mid;
@@ -144,8 +168,9 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) {
       // If std::tm cannot hold some result we resort to a linear search,
       // ignoring all failed conversions.  Slow, but never really happens.
       while (++lo != hi) {
-        if (std::tm* tmp = local_time(&lo, &tm)) {
-          if (get_offset_abbr(*tmp).first == offset) break;
+        tmp = local_time(&lo, &tm);
+        if (tmp != nullptr) {
+          if (tm_gmtoff(*tmp) == offset) break;
         }
       }
       return lo;
@@ -191,8 +216,8 @@ time_zone::absolute_lookup TimeZoneLibC::BreakTime(
   const year_t year = tmp->tm_year + year_t{1900};
   al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday,
                        tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-  std::tie(al.offset, al.abbr) = get_offset_abbr(*tmp);
-  if (!local_) al.abbr = "UTC";  // as expected by cctz
+  al.offset = static_cast<int>(tm_gmtoff(*tmp));
+  al.abbr = local_ ? tm_zone(*tmp) : "UTC";  // as expected by cctz
   al.is_dst = tmp->tm_isdst > 0;
   return al;
 }
diff --git a/src/time_zone_lookup.cc b/src/time_zone_lookup.cc
index 2a38a9b..d0f367c 100644
--- a/src/time_zone_lookup.cc
+++ b/src/time_zone_lookup.cc
@@ -16,7 +16,7 @@
 
 #if defined(__ANDROID__)
 #include <sys/system_properties.h>
-#if __ANDROID_API__ >= 21
+#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 #include <dlfcn.h>
 #endif
 #endif
@@ -26,6 +26,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>
@@ -35,7 +42,7 @@
 
 namespace cctz {
 
-#if defined(__ANDROID__) && __ANDROID_API__ >= 21
+#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21
 namespace {
 // Android 'L' removes __system_property_get() from the NDK, however
 // it is still a hidden symbol in libc so we use dlsym() to access it.
@@ -139,6 +146,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/src/time_zone_lookup_test.cc b/src/time_zone_lookup_test.cc
index 14e3f66..772e817 100644
--- a/src/time_zone_lookup_test.cc
+++ b/src/time_zone_lookup_test.cc
@@ -209,6 +209,7 @@ const char* const kTimeZoneNames[] = {
   "America/North_Dakota/Beulah",
   "America/North_Dakota/Center",
   "America/North_Dakota/New_Salem",
+  "America/Nuuk",
   "America/Ojinaga",
   "America/Panama",
   "America/Pangnirtung",
@@ -576,6 +577,7 @@ const char* const kTimeZoneNames[] = {
   "Pacific/Guam",
   "Pacific/Honolulu",
   "Pacific/Johnston",
+  "Pacific/Kanton",
   "Pacific/Kiritimati",
   "Pacific/Kosrae",
   "Pacific/Kwajalein",
@@ -713,6 +715,18 @@ TEST(TimeZones, LoadZonesConcurrently) {
   EXPECT_LE(failures.size(), max_failures) << testing::PrintToString(failures);
 }
 
+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());
@@ -832,7 +846,7 @@ TEST(BreakTime, LocalTimeInUTC) {
   const time_zone tz = utc_time_zone();
   const auto tp = chrono::system_clock::from_time_t(0);
   ExpectTime(tp, tz, 1970, 1, 1, 0, 0, 0, 0, false, "UTC");
-  EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::thursday, get_weekday(convert(tp, tz)));
 }
 
 TEST(BreakTime, LocalTimeInUTCUnaligned) {
@@ -840,7 +854,7 @@ TEST(BreakTime, LocalTimeInUTCUnaligned) {
   const auto tp =
       chrono::system_clock::from_time_t(0) - chrono::milliseconds(500);
   ExpectTime(tp, tz, 1969, 12, 31, 23, 59, 59, 0, false, "UTC");
-  EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::wednesday, get_weekday(convert(tp, tz)));
 }
 
 TEST(BreakTime, LocalTimePosix) {
@@ -848,7 +862,7 @@ TEST(BreakTime, LocalTimePosix) {
   const time_zone tz = utc_time_zone();
   const auto tp = chrono::system_clock::from_time_t(536457599);
   ExpectTime(tp, tz, 1986, 12, 31, 23, 59, 59, 0, false, "UTC");
-  EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::wednesday, get_weekday(convert(tp, tz)));
 }
 
 TEST(TimeZoneImpl, LocalTimeInFixed) {
@@ -858,28 +872,28 @@ TEST(TimeZoneImpl, LocalTimeInFixed) {
   const auto tp = chrono::system_clock::from_time_t(0);
   ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false,
              "-083347");
-  EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::wednesday, get_weekday(convert(tp, tz)));
 }
 
 TEST(BreakTime, LocalTimeInNewYork) {
   const time_zone tz = LoadZone("America/New_York");
   const auto tp = chrono::system_clock::from_time_t(45);
   ExpectTime(tp, tz, 1969, 12, 31, 19, 0, 45, -5 * 60 * 60, false, "EST");
-  EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::wednesday, get_weekday(convert(tp, tz)));
 }
 
 TEST(BreakTime, LocalTimeInMTV) {
   const time_zone tz = LoadZone("America/Los_Angeles");
   const auto tp = chrono::system_clock::from_time_t(1380855729);
   ExpectTime(tp, tz, 2013, 10, 3, 20, 2, 9, -7 * 60 * 60, true, "PDT");
-  EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::thursday, get_weekday(convert(tp, tz)));
 }
 
 TEST(BreakTime, LocalTimeInSydney) {
   const time_zone tz = LoadZone("Australia/Sydney");
   const auto tp = chrono::system_clock::from_time_t(90);
   ExpectTime(tp, tz, 1970, 1, 1, 10, 1, 30, 10 * 60 * 60, false, "AEST");
-  EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::thursday, get_weekday(convert(tp, tz)));
 }
 
 TEST(MakeTime, TimePointResolution) {
@@ -928,7 +942,7 @@ TEST(MakeTime, Normalization) {
 
 // NOTE: Run this with -ftrapv to detect overflow problems.
 TEST(MakeTime, SysSecondsLimits) {
-  const char RFC3339[] =  "%Y-%m-%dT%H:%M:%S%Ez";
+  const char RFC3339[] =  "%Y-%m-%d%ET%H:%M:%S%Ez";
   const time_zone utc = utc_time_zone();
   const time_zone east = fixed_time_zone(chrono::hours(14));
   const time_zone west = fixed_time_zone(-chrono::hours(14));
@@ -999,13 +1013,21 @@ TEST(MakeTime, SysSecondsLimits) {
 #if defined(_WIN32) || defined(_WIN64)
     // localtime_s() and gmtime_s() don't believe in years outside [1970:3000].
 #else
-    const time_zone utc = LoadZone("libc:UTC");
+    const time_zone cut = LoadZone("libc:UTC");
     const year_t max_tm_year = year_t{std::numeric_limits<int>::max()} + 1900;
-    tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), utc);
-    EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, utc));
+    tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), cut);
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+    // The BSD gmtime_r() fails on extreme positive tm_year values.
+#else
+    EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, cut));
+#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), utc);
-    EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, utc));
+    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
   }
 }
@@ -1024,17 +1046,17 @@ TEST(MakeTime, LocalTimeLibC) {
     ASSERT_EQ(0, setenv("TZ", *np, 1));  // change what "localtime" means
     const auto zi = local_time_zone();
     const auto lc = LoadZone("libc:localtime");
-    time_zone::civil_transition trans;
+    time_zone::civil_transition transition;
     for (auto tp = zi.lookup(civil_second()).trans;
-         zi.next_transition(tp, &trans);
-         tp = zi.lookup(trans.to).trans) {
-      const auto fcl = zi.lookup(trans.from);
-      const auto tcl = zi.lookup(trans.to);
+         zi.next_transition(tp, &transition);
+         tp = zi.lookup(transition.to).trans) {
+      const auto fcl = zi.lookup(transition.from);
+      const auto tcl = zi.lookup(transition.to);
       civil_second cs;  // compare cs in zi and lc
       if (fcl.kind == time_zone::civil_lookup::UNIQUE) {
         if (tcl.kind == time_zone::civil_lookup::UNIQUE) {
           // Both unique; must be an is_dst or abbr change.
-          ASSERT_EQ(trans.from, trans.to);
+          ASSERT_EQ(transition.from, transition.to);
           const auto trans = fcl.trans;
           const auto tal = zi.lookup(trans);
           const auto tprev = trans - cctz::seconds(1);
@@ -1045,11 +1067,11 @@ TEST(MakeTime, LocalTimeLibC) {
           continue;
         }
         ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind);
-        cs = trans.to;
+        cs = transition.to;
       } else {
         ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind);
         ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind);
-        cs = trans.from;
+        cs = transition.from;
       }
       if (cs.year() > 2037) break;  // limit test time (and to 32-bit time_t)
       const auto cl_zi = zi.lookup(cs);
@@ -1156,6 +1178,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<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 - 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");
 
@@ -1270,10 +1330,10 @@ TEST(TimeZoneEdgeCase, PacificApia) {
   //   1325239200 == Sat, 31 Dec 2011 00:00:00 +1400 (+14)
   auto tp = convert(civil_second(2011, 12, 29, 23, 59, 59), tz);
   ExpectTime(tp, tz, 2011, 12, 29, 23, 59, 59, -10 * 3600, true, "-10");
-  EXPECT_EQ(363, get_yearday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(363, get_yearday(convert(tp, tz)));
   tp += cctz::seconds(1);
   ExpectTime(tp, tz, 2011, 12, 31, 0, 0, 0, 14 * 3600, true, "+14");
-  EXPECT_EQ(365, get_yearday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(365, get_yearday(convert(tp, tz)));
 }
 
 TEST(TimeZoneEdgeCase, AfricaCairo) {
@@ -1395,10 +1455,10 @@ TEST(TimeZoneEdgeCase, NegativeYear) {
   const time_zone tz = utc_time_zone();
   auto tp = convert(civil_second(0, 1, 1, 0, 0, 0), tz);
   ExpectTime(tp, tz, 0, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC");
-  EXPECT_EQ(weekday::saturday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::saturday, get_weekday(convert(tp, tz)));
   tp -= cctz::seconds(1);
   ExpectTime(tp, tz, -1, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC");
-  EXPECT_EQ(weekday::friday, get_weekday(civil_day(convert(tp, tz))));
+  EXPECT_EQ(weekday::friday, get_weekday(convert(tp, tz)));
 }
 
 TEST(TimeZoneEdgeCase, UTC32bitLimit) {
diff --git a/src/time_zone_posix.cc b/src/time_zone_posix.cc
index 1415cb6..847db17 100644
--- a/src/time_zone_posix.cc
+++ b/src/time_zone_posix.cc
@@ -98,9 +98,9 @@ const char* ParseDateTime(const char* p, PosixTransition* res) {
           int weekday = 0;
           if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) {
             res->date.fmt = PosixTransition::M;
-            res->date.m.month = static_cast<int_fast8_t>(month);
-            res->date.m.week = static_cast<int_fast8_t>(week);
-            res->date.m.weekday = static_cast<int_fast8_t>(weekday);
+            res->date.m.month = static_cast<std::int_fast8_t>(month);
+            res->date.m.week = static_cast<std::int_fast8_t>(week);
+            res->date.m.weekday = static_cast<std::int_fast8_t>(weekday);
           }
         }
       }
@@ -108,13 +108,13 @@ const char* ParseDateTime(const char* p, PosixTransition* res) {
       int day = 0;
       if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) {
         res->date.fmt = PosixTransition::J;
-        res->date.j.day = static_cast<int_fast16_t>(day);
+        res->date.j.day = static_cast<std::int_fast16_t>(day);
       }
     } else {
       int day = 0;
       if ((p = ParseInt(p, 0, 365, &day)) != nullptr) {
         res->date.fmt = PosixTransition::N;
-        res->date.j.day = static_cast<int_fast16_t>(day);
+        res->date.n.day = static_cast<std::int_fast16_t>(day);
       }
     }
   }
diff --git a/src/tzfile.h b/src/tzfile.h
index 446c8d5..9c3ea4e 100644
--- a/src/tzfile.h
+++ b/src/tzfile.h
@@ -44,9 +44,9 @@
 
 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_ttisgmtcnt[4];	/* coded number of trans. time flags */
+	char	tzh_ttisutcnt[4];	/* coded number of trans. time flags */
 	char	tzh_ttisstdcnt[4];	/* coded number of trans. time flags */
 	char	tzh_leapcnt[4];		/* coded number of leap seconds */
 	char	tzh_timecnt[4];		/* coded number of transition times */
@@ -69,14 +69,15 @@ struct tzhead {
 **		one (char [4])		total correction after above
 **	tzh_ttisstdcnt (char)s		indexed by type; if 1, transition
 **					time is standard time, if 0,
-**					transition time is wall clock time
-**					if absent, transition times are
-**					assumed to be wall clock time
-**	tzh_ttisgmtcnt (char)s		indexed by type; if 1, transition
-**					time is UT, if 0,
-**					transition time is local time
-**					if absent, transition times are
+**					transition time is local (wall clock)
+**					time; if absent, transition times are
 **					assumed to be local time
+**	tzh_ttisutcnt (char)s		indexed by type; if 1, transition
+**					time is UT, if 0, transition time is
+**					local time; if absent, transition
+**					times are assumed to be local time.
+**					When this is 1, the corresponding
+**					std/wall indicator must also be 1.
 */
 
 /*
diff --git a/src/zone_info_source.cc b/src/zone_info_source.cc
index 9012fe4..e061f38 100644
--- a/src/zone_info_source.cc
+++ b/src/zone_info_source.cc
@@ -40,11 +40,20 @@ std::unique_ptr<cctz::ZoneInfoSource> DefaultFactory(
 // A "weak" definition for cctz_extension::zone_info_source_factory.
 // The user may override this with their own "strong" definition (see
 // zone_info_source.h).
-#if defined(_MSC_VER)
+#if !defined(__has_attribute)
+#define __has_attribute(x) 0
+#endif
+// MinGW is GCC on Windows, so while it asserts __has_attribute(weak), the
+// Windows linker cannot handle that. Nor does the MinGW compiler know how to
+// pass "#pragma comment(linker, ...)" to the Windows linker.
+#if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__)
+ZoneInfoSourceFactory zone_info_source_factory
+    __attribute__((weak)) = DefaultFactory;
+#elif defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBCPP_VERSION)
 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@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA")
@@ -54,18 +63,10 @@ ZoneInfoSourceFactory default_factory = DefaultFactory;
     "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZEA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZEA")
 #else
 #error Unsupported MSVC platform
-#endif
-#else  // _MSC_VER
-#if !defined(__has_attribute)
-#define __has_attribute(x) 0
-#endif
-#if __has_attribute(weak) || defined(__GNUC__)
-ZoneInfoSourceFactory zone_info_source_factory
-    __attribute__((weak)) = DefaultFactory;
+#endif  // _M_<PLATFORM>
 #else
 // Make it a "strong" definition if we have no other choice.
 ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory;
 #endif
-#endif  // _MSC_VER
 
 }  // namespace cctz_extension
diff --git a/testdata/README.zoneinfo b/testdata/README.zoneinfo
new file mode 100644
index 0000000..a41c7b8
--- /dev/null
+++ b/testdata/README.zoneinfo
@@ -0,0 +1,42 @@
+testdata/zoneinfo contains time-zone data files that may be used with CCTZ.
+Install them in a location referenced by the ${TZDIR} environment variable.
+Symbolic and hard links have been eliminated for portability.
+
+On Linux systems the distribution's versions of these files can probably
+already be found in the default ${TZDIR} location, /usr/share/zoneinfo.
+
+New versions can be generated using the following shell script.
+
+  #!/bin/sh -
+  set -e
+  DESTDIR=$(mktemp -d)
+  trap "rm -fr ${DESTDIR}" 0 2 15
+  (
+    cd ${DESTDIR}
+    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 \
+                TZDIR=/zoneinfo \
+                REDO=posix_only \
+                LOCALTIME=Factory \
+                TZDATA_TEXT= \
+                ZONETABLES=zone1970.tab
+    tar --create --dereference --hard-dereference --file tzfile.tar \
+        --directory=tz tzfile.h
+    tar --create --dereference --hard-dereference --file zoneinfo.tar \
+        --exclude=zoneinfo/posixrules zoneinfo \
+        --directory=tz version
+  )
+  tar --extract --directory src --file ${DESTDIR}/tzfile.tar
+  tar --extract --directory testdata --file ${DESTDIR}/zoneinfo.tar
+  exit 0
+
+To run the CCTZ tests using the testdata/zoneinfo files, execute:
+
+  bazel test --test_env=TZDIR=${PWD}/testdata/zoneinfo ...
diff --git a/testdata/version b/testdata/version
new file mode 100644
index 0000000..ca002de
--- /dev/null
+++ b/testdata/version
@@ -0,0 +1 @@
+2022a
diff --git a/testdata/zoneinfo/Africa/Abidjan b/testdata/zoneinfo/Africa/Abidjan
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Abidjan differ
diff --git a/testdata/zoneinfo/Africa/Accra b/testdata/zoneinfo/Africa/Accra
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Accra differ
diff --git a/testdata/zoneinfo/Africa/Addis_Ababa b/testdata/zoneinfo/Africa/Addis_Ababa
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Addis_Ababa differ
diff --git a/testdata/zoneinfo/Africa/Algiers b/testdata/zoneinfo/Africa/Algiers
new file mode 100644
index 0000000..56a4dd2
Binary files /dev/null and b/testdata/zoneinfo/Africa/Algiers differ
diff --git a/testdata/zoneinfo/Africa/Asmara b/testdata/zoneinfo/Africa/Asmara
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Asmara differ
diff --git a/testdata/zoneinfo/Africa/Asmera b/testdata/zoneinfo/Africa/Asmera
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Asmera differ
diff --git a/testdata/zoneinfo/Africa/Bamako b/testdata/zoneinfo/Africa/Bamako
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Bamako differ
diff --git a/testdata/zoneinfo/Africa/Bangui b/testdata/zoneinfo/Africa/Bangui
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Bangui differ
diff --git a/testdata/zoneinfo/Africa/Banjul b/testdata/zoneinfo/Africa/Banjul
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Banjul differ
diff --git a/testdata/zoneinfo/Africa/Bissau b/testdata/zoneinfo/Africa/Bissau
new file mode 100644
index 0000000..0da1d1e
Binary files /dev/null and b/testdata/zoneinfo/Africa/Bissau differ
diff --git a/testdata/zoneinfo/Africa/Blantyre b/testdata/zoneinfo/Africa/Blantyre
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Blantyre differ
diff --git a/testdata/zoneinfo/Africa/Brazzaville b/testdata/zoneinfo/Africa/Brazzaville
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Brazzaville differ
diff --git a/testdata/zoneinfo/Africa/Bujumbura b/testdata/zoneinfo/Africa/Bujumbura
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Bujumbura differ
diff --git a/testdata/zoneinfo/Africa/Cairo b/testdata/zoneinfo/Africa/Cairo
new file mode 100644
index 0000000..ea38c97
Binary files /dev/null and b/testdata/zoneinfo/Africa/Cairo differ
diff --git a/testdata/zoneinfo/Africa/Casablanca b/testdata/zoneinfo/Africa/Casablanca
new file mode 100644
index 0000000..0263c90
Binary files /dev/null and b/testdata/zoneinfo/Africa/Casablanca differ
diff --git a/testdata/zoneinfo/Africa/Ceuta b/testdata/zoneinfo/Africa/Ceuta
new file mode 100644
index 0000000..a461dce
Binary files /dev/null and b/testdata/zoneinfo/Africa/Ceuta differ
diff --git a/testdata/zoneinfo/Africa/Conakry b/testdata/zoneinfo/Africa/Conakry
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Conakry differ
diff --git a/testdata/zoneinfo/Africa/Dakar b/testdata/zoneinfo/Africa/Dakar
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Dakar differ
diff --git a/testdata/zoneinfo/Africa/Dar_es_Salaam b/testdata/zoneinfo/Africa/Dar_es_Salaam
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Dar_es_Salaam differ
diff --git a/testdata/zoneinfo/Africa/Djibouti b/testdata/zoneinfo/Africa/Djibouti
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Djibouti differ
diff --git a/testdata/zoneinfo/Africa/Douala b/testdata/zoneinfo/Africa/Douala
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Douala differ
diff --git a/testdata/zoneinfo/Africa/El_Aaiun b/testdata/zoneinfo/Africa/El_Aaiun
new file mode 100644
index 0000000..772e23c
Binary files /dev/null and b/testdata/zoneinfo/Africa/El_Aaiun differ
diff --git a/testdata/zoneinfo/Africa/Freetown b/testdata/zoneinfo/Africa/Freetown
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Freetown differ
diff --git a/testdata/zoneinfo/Africa/Gaborone b/testdata/zoneinfo/Africa/Gaborone
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Gaborone differ
diff --git a/testdata/zoneinfo/Africa/Harare b/testdata/zoneinfo/Africa/Harare
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Harare differ
diff --git a/testdata/zoneinfo/Africa/Johannesburg b/testdata/zoneinfo/Africa/Johannesburg
new file mode 100644
index 0000000..bada063
Binary files /dev/null and b/testdata/zoneinfo/Africa/Johannesburg differ
diff --git a/testdata/zoneinfo/Africa/Juba b/testdata/zoneinfo/Africa/Juba
new file mode 100644
index 0000000..0aba9ff
Binary files /dev/null and b/testdata/zoneinfo/Africa/Juba differ
diff --git a/testdata/zoneinfo/Africa/Kampala b/testdata/zoneinfo/Africa/Kampala
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Kampala differ
diff --git a/testdata/zoneinfo/Africa/Khartoum b/testdata/zoneinfo/Africa/Khartoum
new file mode 100644
index 0000000..3f8e44b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Khartoum differ
diff --git a/testdata/zoneinfo/Africa/Kigali b/testdata/zoneinfo/Africa/Kigali
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Kigali differ
diff --git a/testdata/zoneinfo/Africa/Kinshasa b/testdata/zoneinfo/Africa/Kinshasa
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Kinshasa differ
diff --git a/testdata/zoneinfo/Africa/Lagos b/testdata/zoneinfo/Africa/Lagos
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Lagos differ
diff --git a/testdata/zoneinfo/Africa/Libreville b/testdata/zoneinfo/Africa/Libreville
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Libreville differ
diff --git a/testdata/zoneinfo/Africa/Lome b/testdata/zoneinfo/Africa/Lome
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Lome differ
diff --git a/testdata/zoneinfo/Africa/Luanda b/testdata/zoneinfo/Africa/Luanda
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Luanda differ
diff --git a/testdata/zoneinfo/Africa/Lubumbashi b/testdata/zoneinfo/Africa/Lubumbashi
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Lubumbashi differ
diff --git a/testdata/zoneinfo/Africa/Lusaka b/testdata/zoneinfo/Africa/Lusaka
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Lusaka differ
diff --git a/testdata/zoneinfo/Africa/Malabo b/testdata/zoneinfo/Africa/Malabo
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Malabo differ
diff --git a/testdata/zoneinfo/Africa/Maputo b/testdata/zoneinfo/Africa/Maputo
new file mode 100644
index 0000000..651e5cf
Binary files /dev/null and b/testdata/zoneinfo/Africa/Maputo differ
diff --git a/testdata/zoneinfo/Africa/Maseru b/testdata/zoneinfo/Africa/Maseru
new file mode 100644
index 0000000..bada063
Binary files /dev/null and b/testdata/zoneinfo/Africa/Maseru differ
diff --git a/testdata/zoneinfo/Africa/Mbabane b/testdata/zoneinfo/Africa/Mbabane
new file mode 100644
index 0000000..bada063
Binary files /dev/null and b/testdata/zoneinfo/Africa/Mbabane differ
diff --git a/testdata/zoneinfo/Africa/Mogadishu b/testdata/zoneinfo/Africa/Mogadishu
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Mogadishu differ
diff --git a/testdata/zoneinfo/Africa/Monrovia b/testdata/zoneinfo/Africa/Monrovia
new file mode 100644
index 0000000..8377809
Binary files /dev/null and b/testdata/zoneinfo/Africa/Monrovia differ
diff --git a/testdata/zoneinfo/Africa/Nairobi b/testdata/zoneinfo/Africa/Nairobi
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Nairobi differ
diff --git a/testdata/zoneinfo/Africa/Ndjamena b/testdata/zoneinfo/Africa/Ndjamena
new file mode 100644
index 0000000..ecbc096
Binary files /dev/null and b/testdata/zoneinfo/Africa/Ndjamena differ
diff --git a/testdata/zoneinfo/Africa/Niamey b/testdata/zoneinfo/Africa/Niamey
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Niamey differ
diff --git a/testdata/zoneinfo/Africa/Nouakchott b/testdata/zoneinfo/Africa/Nouakchott
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Nouakchott differ
diff --git a/testdata/zoneinfo/Africa/Ouagadougou b/testdata/zoneinfo/Africa/Ouagadougou
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Ouagadougou differ
diff --git a/testdata/zoneinfo/Africa/Porto-Novo b/testdata/zoneinfo/Africa/Porto-Novo
new file mode 100644
index 0000000..3d7a71b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Porto-Novo differ
diff --git a/testdata/zoneinfo/Africa/Sao_Tome b/testdata/zoneinfo/Africa/Sao_Tome
new file mode 100644
index 0000000..425ad3f
Binary files /dev/null and b/testdata/zoneinfo/Africa/Sao_Tome differ
diff --git a/testdata/zoneinfo/Africa/Timbuktu b/testdata/zoneinfo/Africa/Timbuktu
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Africa/Timbuktu differ
diff --git a/testdata/zoneinfo/Africa/Tripoli b/testdata/zoneinfo/Africa/Tripoli
new file mode 100644
index 0000000..e0c8997
Binary files /dev/null and b/testdata/zoneinfo/Africa/Tripoli differ
diff --git a/testdata/zoneinfo/Africa/Tunis b/testdata/zoneinfo/Africa/Tunis
new file mode 100644
index 0000000..ca324cb
Binary files /dev/null and b/testdata/zoneinfo/Africa/Tunis differ
diff --git a/testdata/zoneinfo/Africa/Windhoek b/testdata/zoneinfo/Africa/Windhoek
new file mode 100644
index 0000000..0edc52b
Binary files /dev/null and b/testdata/zoneinfo/Africa/Windhoek differ
diff --git a/testdata/zoneinfo/America/Adak b/testdata/zoneinfo/America/Adak
new file mode 100644
index 0000000..b1497bd
Binary files /dev/null and b/testdata/zoneinfo/America/Adak differ
diff --git a/testdata/zoneinfo/America/Anchorage b/testdata/zoneinfo/America/Anchorage
new file mode 100644
index 0000000..cdf0572
Binary files /dev/null and b/testdata/zoneinfo/America/Anchorage differ
diff --git a/testdata/zoneinfo/America/Anguilla b/testdata/zoneinfo/America/Anguilla
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Anguilla differ
diff --git a/testdata/zoneinfo/America/Antigua b/testdata/zoneinfo/America/Antigua
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Antigua differ
diff --git a/testdata/zoneinfo/America/Araguaina b/testdata/zoneinfo/America/Araguaina
new file mode 100644
index 0000000..f66c9f7
Binary files /dev/null and b/testdata/zoneinfo/America/Araguaina differ
diff --git a/testdata/zoneinfo/America/Argentina/Buenos_Aires b/testdata/zoneinfo/America/Argentina/Buenos_Aires
new file mode 100644
index 0000000..d6f999b
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Buenos_Aires differ
diff --git a/testdata/zoneinfo/America/Argentina/Catamarca b/testdata/zoneinfo/America/Argentina/Catamarca
new file mode 100644
index 0000000..1dcc8d8
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Catamarca differ
diff --git a/testdata/zoneinfo/America/Argentina/ComodRivadavia b/testdata/zoneinfo/America/Argentina/ComodRivadavia
new file mode 100644
index 0000000..1dcc8d8
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/ComodRivadavia differ
diff --git a/testdata/zoneinfo/America/Argentina/Cordoba b/testdata/zoneinfo/America/Argentina/Cordoba
new file mode 100644
index 0000000..35a52e5
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Cordoba differ
diff --git a/testdata/zoneinfo/America/Argentina/Jujuy b/testdata/zoneinfo/America/Argentina/Jujuy
new file mode 100644
index 0000000..b275f27
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Jujuy differ
diff --git a/testdata/zoneinfo/America/Argentina/La_Rioja b/testdata/zoneinfo/America/Argentina/La_Rioja
new file mode 100644
index 0000000..23fca12
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/La_Rioja differ
diff --git a/testdata/zoneinfo/America/Argentina/Mendoza b/testdata/zoneinfo/America/Argentina/Mendoza
new file mode 100644
index 0000000..691c569
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Mendoza differ
diff --git a/testdata/zoneinfo/America/Argentina/Rio_Gallegos b/testdata/zoneinfo/America/Argentina/Rio_Gallegos
new file mode 100644
index 0000000..991d1fa
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Rio_Gallegos differ
diff --git a/testdata/zoneinfo/America/Argentina/Salta b/testdata/zoneinfo/America/Argentina/Salta
new file mode 100644
index 0000000..58863e0
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Salta differ
diff --git a/testdata/zoneinfo/America/Argentina/San_Juan b/testdata/zoneinfo/America/Argentina/San_Juan
new file mode 100644
index 0000000..7eba33c
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/San_Juan differ
diff --git a/testdata/zoneinfo/America/Argentina/San_Luis b/testdata/zoneinfo/America/Argentina/San_Luis
new file mode 100644
index 0000000..0a81cbd
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/San_Luis differ
diff --git a/testdata/zoneinfo/America/Argentina/Tucuman b/testdata/zoneinfo/America/Argentina/Tucuman
new file mode 100644
index 0000000..10556d5
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Tucuman differ
diff --git a/testdata/zoneinfo/America/Argentina/Ushuaia b/testdata/zoneinfo/America/Argentina/Ushuaia
new file mode 100644
index 0000000..e031750
Binary files /dev/null and b/testdata/zoneinfo/America/Argentina/Ushuaia differ
diff --git a/testdata/zoneinfo/America/Aruba b/testdata/zoneinfo/America/Aruba
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Aruba differ
diff --git a/testdata/zoneinfo/America/Asuncion b/testdata/zoneinfo/America/Asuncion
new file mode 100644
index 0000000..6225036
Binary files /dev/null and b/testdata/zoneinfo/America/Asuncion differ
diff --git a/testdata/zoneinfo/America/Atikokan b/testdata/zoneinfo/America/Atikokan
new file mode 100644
index 0000000..9154643
Binary files /dev/null and b/testdata/zoneinfo/America/Atikokan differ
diff --git a/testdata/zoneinfo/America/Atka b/testdata/zoneinfo/America/Atka
new file mode 100644
index 0000000..b1497bd
Binary files /dev/null and b/testdata/zoneinfo/America/Atka differ
diff --git a/testdata/zoneinfo/America/Bahia b/testdata/zoneinfo/America/Bahia
new file mode 100644
index 0000000..7969e30
Binary files /dev/null and b/testdata/zoneinfo/America/Bahia differ
diff --git a/testdata/zoneinfo/America/Bahia_Banderas b/testdata/zoneinfo/America/Bahia_Banderas
new file mode 100644
index 0000000..cbe22a7
Binary files /dev/null and b/testdata/zoneinfo/America/Bahia_Banderas differ
diff --git a/testdata/zoneinfo/America/Barbados b/testdata/zoneinfo/America/Barbados
new file mode 100644
index 0000000..720c986
Binary files /dev/null and b/testdata/zoneinfo/America/Barbados differ
diff --git a/testdata/zoneinfo/America/Belem b/testdata/zoneinfo/America/Belem
new file mode 100644
index 0000000..e0d7653
Binary files /dev/null and b/testdata/zoneinfo/America/Belem differ
diff --git a/testdata/zoneinfo/America/Belize b/testdata/zoneinfo/America/Belize
new file mode 100644
index 0000000..bfc19f4
Binary files /dev/null and b/testdata/zoneinfo/America/Belize differ
diff --git a/testdata/zoneinfo/America/Blanc-Sablon b/testdata/zoneinfo/America/Blanc-Sablon
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Blanc-Sablon differ
diff --git a/testdata/zoneinfo/America/Boa_Vista b/testdata/zoneinfo/America/Boa_Vista
new file mode 100644
index 0000000..fca9720
Binary files /dev/null and b/testdata/zoneinfo/America/Boa_Vista differ
diff --git a/testdata/zoneinfo/America/Bogota b/testdata/zoneinfo/America/Bogota
new file mode 100644
index 0000000..6cb53d4
Binary files /dev/null and b/testdata/zoneinfo/America/Bogota differ
diff --git a/testdata/zoneinfo/America/Boise b/testdata/zoneinfo/America/Boise
new file mode 100644
index 0000000..72fec9e
Binary files /dev/null and b/testdata/zoneinfo/America/Boise differ
diff --git a/testdata/zoneinfo/America/Buenos_Aires b/testdata/zoneinfo/America/Buenos_Aires
new file mode 100644
index 0000000..d6f999b
Binary files /dev/null and b/testdata/zoneinfo/America/Buenos_Aires differ
diff --git a/testdata/zoneinfo/America/Cambridge_Bay b/testdata/zoneinfo/America/Cambridge_Bay
new file mode 100644
index 0000000..0a22252
Binary files /dev/null and b/testdata/zoneinfo/America/Cambridge_Bay differ
diff --git a/testdata/zoneinfo/America/Campo_Grande b/testdata/zoneinfo/America/Campo_Grande
new file mode 100644
index 0000000..6855e4e
Binary files /dev/null and b/testdata/zoneinfo/America/Campo_Grande differ
diff --git a/testdata/zoneinfo/America/Cancun b/testdata/zoneinfo/America/Cancun
new file mode 100644
index 0000000..640b259
Binary files /dev/null and b/testdata/zoneinfo/America/Cancun differ
diff --git a/testdata/zoneinfo/America/Caracas b/testdata/zoneinfo/America/Caracas
new file mode 100644
index 0000000..8dbe6ff
Binary files /dev/null and b/testdata/zoneinfo/America/Caracas differ
diff --git a/testdata/zoneinfo/America/Catamarca b/testdata/zoneinfo/America/Catamarca
new file mode 100644
index 0000000..1dcc8d8
Binary files /dev/null and b/testdata/zoneinfo/America/Catamarca differ
diff --git a/testdata/zoneinfo/America/Cayenne b/testdata/zoneinfo/America/Cayenne
new file mode 100644
index 0000000..cd49f05
Binary files /dev/null and b/testdata/zoneinfo/America/Cayenne differ
diff --git a/testdata/zoneinfo/America/Cayman b/testdata/zoneinfo/America/Cayman
new file mode 100644
index 0000000..9154643
Binary files /dev/null and b/testdata/zoneinfo/America/Cayman differ
diff --git a/testdata/zoneinfo/America/Chicago b/testdata/zoneinfo/America/Chicago
new file mode 100644
index 0000000..b016880
Binary files /dev/null and b/testdata/zoneinfo/America/Chicago differ
diff --git a/testdata/zoneinfo/America/Chihuahua b/testdata/zoneinfo/America/Chihuahua
new file mode 100644
index 0000000..e1780a5
Binary files /dev/null and b/testdata/zoneinfo/America/Chihuahua differ
diff --git a/testdata/zoneinfo/America/Coral_Harbour b/testdata/zoneinfo/America/Coral_Harbour
new file mode 100644
index 0000000..9154643
Binary files /dev/null and b/testdata/zoneinfo/America/Coral_Harbour differ
diff --git a/testdata/zoneinfo/America/Cordoba b/testdata/zoneinfo/America/Cordoba
new file mode 100644
index 0000000..35a52e5
Binary files /dev/null and b/testdata/zoneinfo/America/Cordoba differ
diff --git a/testdata/zoneinfo/America/Costa_Rica b/testdata/zoneinfo/America/Costa_Rica
new file mode 100644
index 0000000..08f0128
Binary files /dev/null and b/testdata/zoneinfo/America/Costa_Rica differ
diff --git a/testdata/zoneinfo/America/Creston b/testdata/zoneinfo/America/Creston
new file mode 100644
index 0000000..c2bd2f9
Binary files /dev/null and b/testdata/zoneinfo/America/Creston differ
diff --git a/testdata/zoneinfo/America/Cuiaba b/testdata/zoneinfo/America/Cuiaba
new file mode 100644
index 0000000..c09a875
Binary files /dev/null and b/testdata/zoneinfo/America/Cuiaba differ
diff --git a/testdata/zoneinfo/America/Curacao b/testdata/zoneinfo/America/Curacao
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Curacao differ
diff --git a/testdata/zoneinfo/America/Danmarkshavn b/testdata/zoneinfo/America/Danmarkshavn
new file mode 100644
index 0000000..8718efc
Binary files /dev/null and b/testdata/zoneinfo/America/Danmarkshavn differ
diff --git a/testdata/zoneinfo/America/Dawson b/testdata/zoneinfo/America/Dawson
new file mode 100644
index 0000000..07e4c5f
Binary files /dev/null and b/testdata/zoneinfo/America/Dawson differ
diff --git a/testdata/zoneinfo/America/Dawson_Creek b/testdata/zoneinfo/America/Dawson_Creek
new file mode 100644
index 0000000..761d1d9
Binary files /dev/null and b/testdata/zoneinfo/America/Dawson_Creek differ
diff --git a/testdata/zoneinfo/America/Denver b/testdata/zoneinfo/America/Denver
new file mode 100644
index 0000000..09e54e5
Binary files /dev/null and b/testdata/zoneinfo/America/Denver differ
diff --git a/testdata/zoneinfo/America/Detroit b/testdata/zoneinfo/America/Detroit
new file mode 100644
index 0000000..6eb3ac4
Binary files /dev/null and b/testdata/zoneinfo/America/Detroit differ
diff --git a/testdata/zoneinfo/America/Dominica b/testdata/zoneinfo/America/Dominica
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Dominica differ
diff --git a/testdata/zoneinfo/America/Edmonton b/testdata/zoneinfo/America/Edmonton
new file mode 100644
index 0000000..645ee94
Binary files /dev/null and b/testdata/zoneinfo/America/Edmonton differ
diff --git a/testdata/zoneinfo/America/Eirunepe b/testdata/zoneinfo/America/Eirunepe
new file mode 100644
index 0000000..7da4b98
Binary files /dev/null and b/testdata/zoneinfo/America/Eirunepe differ
diff --git a/testdata/zoneinfo/America/El_Salvador b/testdata/zoneinfo/America/El_Salvador
new file mode 100644
index 0000000..4348411
Binary files /dev/null and b/testdata/zoneinfo/America/El_Salvador differ
diff --git a/testdata/zoneinfo/America/Ensenada b/testdata/zoneinfo/America/Ensenada
new file mode 100644
index 0000000..19ccd35
Binary files /dev/null and b/testdata/zoneinfo/America/Ensenada differ
diff --git a/testdata/zoneinfo/America/Fort_Nelson b/testdata/zoneinfo/America/Fort_Nelson
new file mode 100644
index 0000000..2a49c6c
Binary files /dev/null and b/testdata/zoneinfo/America/Fort_Nelson differ
diff --git a/testdata/zoneinfo/America/Fort_Wayne b/testdata/zoneinfo/America/Fort_Wayne
new file mode 100644
index 0000000..6b08d15
Binary files /dev/null and b/testdata/zoneinfo/America/Fort_Wayne differ
diff --git a/testdata/zoneinfo/America/Fortaleza b/testdata/zoneinfo/America/Fortaleza
new file mode 100644
index 0000000..092e40d
Binary files /dev/null and b/testdata/zoneinfo/America/Fortaleza differ
diff --git a/testdata/zoneinfo/America/Glace_Bay b/testdata/zoneinfo/America/Glace_Bay
new file mode 100644
index 0000000..f85eb34
Binary files /dev/null and b/testdata/zoneinfo/America/Glace_Bay differ
diff --git a/testdata/zoneinfo/America/Godthab b/testdata/zoneinfo/America/Godthab
new file mode 100644
index 0000000..4ddc99d
Binary files /dev/null and b/testdata/zoneinfo/America/Godthab differ
diff --git a/testdata/zoneinfo/America/Goose_Bay b/testdata/zoneinfo/America/Goose_Bay
new file mode 100644
index 0000000..820e0dd
Binary files /dev/null and b/testdata/zoneinfo/America/Goose_Bay differ
diff --git a/testdata/zoneinfo/America/Grand_Turk b/testdata/zoneinfo/America/Grand_Turk
new file mode 100644
index 0000000..9d90e74
Binary files /dev/null and b/testdata/zoneinfo/America/Grand_Turk differ
diff --git a/testdata/zoneinfo/America/Grenada b/testdata/zoneinfo/America/Grenada
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Grenada differ
diff --git a/testdata/zoneinfo/America/Guadeloupe b/testdata/zoneinfo/America/Guadeloupe
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Guadeloupe differ
diff --git a/testdata/zoneinfo/America/Guatemala b/testdata/zoneinfo/America/Guatemala
new file mode 100644
index 0000000..8aa8e58
Binary files /dev/null and b/testdata/zoneinfo/America/Guatemala differ
diff --git a/testdata/zoneinfo/America/Guayaquil b/testdata/zoneinfo/America/Guayaquil
new file mode 100644
index 0000000..381ae6c
Binary files /dev/null and b/testdata/zoneinfo/America/Guayaquil differ
diff --git a/testdata/zoneinfo/America/Guyana b/testdata/zoneinfo/America/Guyana
new file mode 100644
index 0000000..bcc6688
Binary files /dev/null and b/testdata/zoneinfo/America/Guyana differ
diff --git a/testdata/zoneinfo/America/Halifax b/testdata/zoneinfo/America/Halifax
new file mode 100644
index 0000000..9fa850a
Binary files /dev/null and b/testdata/zoneinfo/America/Halifax differ
diff --git a/testdata/zoneinfo/America/Havana b/testdata/zoneinfo/America/Havana
new file mode 100644
index 0000000..e06629d
Binary files /dev/null and b/testdata/zoneinfo/America/Havana differ
diff --git a/testdata/zoneinfo/America/Hermosillo b/testdata/zoneinfo/America/Hermosillo
new file mode 100644
index 0000000..8283239
Binary files /dev/null and b/testdata/zoneinfo/America/Hermosillo differ
diff --git a/testdata/zoneinfo/America/Indiana/Indianapolis b/testdata/zoneinfo/America/Indiana/Indianapolis
new file mode 100644
index 0000000..6b08d15
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Indianapolis differ
diff --git a/testdata/zoneinfo/America/Indiana/Knox b/testdata/zoneinfo/America/Indiana/Knox
new file mode 100644
index 0000000..b187d5f
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Knox differ
diff --git a/testdata/zoneinfo/America/Indiana/Marengo b/testdata/zoneinfo/America/Indiana/Marengo
new file mode 100644
index 0000000..a730fe6
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Marengo differ
diff --git a/testdata/zoneinfo/America/Indiana/Petersburg b/testdata/zoneinfo/America/Indiana/Petersburg
new file mode 100644
index 0000000..341a023
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Petersburg differ
diff --git a/testdata/zoneinfo/America/Indiana/Tell_City b/testdata/zoneinfo/America/Indiana/Tell_City
new file mode 100644
index 0000000..76e1f62
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Tell_City differ
diff --git a/testdata/zoneinfo/America/Indiana/Vevay b/testdata/zoneinfo/America/Indiana/Vevay
new file mode 100644
index 0000000..f2acf6c
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Vevay differ
diff --git a/testdata/zoneinfo/America/Indiana/Vincennes b/testdata/zoneinfo/America/Indiana/Vincennes
new file mode 100644
index 0000000..c255f89
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Vincennes differ
diff --git a/testdata/zoneinfo/America/Indiana/Winamac b/testdata/zoneinfo/America/Indiana/Winamac
new file mode 100644
index 0000000..8700ed9
Binary files /dev/null and b/testdata/zoneinfo/America/Indiana/Winamac differ
diff --git a/testdata/zoneinfo/America/Indianapolis b/testdata/zoneinfo/America/Indianapolis
new file mode 100644
index 0000000..6b08d15
Binary files /dev/null and b/testdata/zoneinfo/America/Indianapolis differ
diff --git a/testdata/zoneinfo/America/Inuvik b/testdata/zoneinfo/America/Inuvik
new file mode 100644
index 0000000..af3107d
Binary files /dev/null and b/testdata/zoneinfo/America/Inuvik differ
diff --git a/testdata/zoneinfo/America/Iqaluit b/testdata/zoneinfo/America/Iqaluit
new file mode 100644
index 0000000..eb2c99c
Binary files /dev/null and b/testdata/zoneinfo/America/Iqaluit differ
diff --git a/testdata/zoneinfo/America/Jamaica b/testdata/zoneinfo/America/Jamaica
new file mode 100644
index 0000000..be6b1b6
Binary files /dev/null and b/testdata/zoneinfo/America/Jamaica differ
diff --git a/testdata/zoneinfo/America/Jujuy b/testdata/zoneinfo/America/Jujuy
new file mode 100644
index 0000000..b275f27
Binary files /dev/null and b/testdata/zoneinfo/America/Jujuy differ
diff --git a/testdata/zoneinfo/America/Juneau b/testdata/zoneinfo/America/Juneau
new file mode 100644
index 0000000..e347b36
Binary files /dev/null and b/testdata/zoneinfo/America/Juneau differ
diff --git a/testdata/zoneinfo/America/Kentucky/Louisville b/testdata/zoneinfo/America/Kentucky/Louisville
new file mode 100644
index 0000000..f2136d6
Binary files /dev/null and b/testdata/zoneinfo/America/Kentucky/Louisville differ
diff --git a/testdata/zoneinfo/America/Kentucky/Monticello b/testdata/zoneinfo/America/Kentucky/Monticello
new file mode 100644
index 0000000..d9f54a1
Binary files /dev/null and b/testdata/zoneinfo/America/Kentucky/Monticello differ
diff --git a/testdata/zoneinfo/America/Knox_IN b/testdata/zoneinfo/America/Knox_IN
new file mode 100644
index 0000000..b187d5f
Binary files /dev/null and b/testdata/zoneinfo/America/Knox_IN differ
diff --git a/testdata/zoneinfo/America/Kralendijk b/testdata/zoneinfo/America/Kralendijk
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Kralendijk differ
diff --git a/testdata/zoneinfo/America/La_Paz b/testdata/zoneinfo/America/La_Paz
new file mode 100644
index 0000000..68ddaae
Binary files /dev/null and b/testdata/zoneinfo/America/La_Paz differ
diff --git a/testdata/zoneinfo/America/Lima b/testdata/zoneinfo/America/Lima
new file mode 100644
index 0000000..b643c55
Binary files /dev/null and b/testdata/zoneinfo/America/Lima differ
diff --git a/testdata/zoneinfo/America/Los_Angeles b/testdata/zoneinfo/America/Los_Angeles
new file mode 100644
index 0000000..aaf0778
Binary files /dev/null and b/testdata/zoneinfo/America/Los_Angeles differ
diff --git a/testdata/zoneinfo/America/Louisville b/testdata/zoneinfo/America/Louisville
new file mode 100644
index 0000000..f2136d6
Binary files /dev/null and b/testdata/zoneinfo/America/Louisville differ
diff --git a/testdata/zoneinfo/America/Lower_Princes b/testdata/zoneinfo/America/Lower_Princes
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Lower_Princes differ
diff --git a/testdata/zoneinfo/America/Maceio b/testdata/zoneinfo/America/Maceio
new file mode 100644
index 0000000..dbb8d57
Binary files /dev/null and b/testdata/zoneinfo/America/Maceio differ
diff --git a/testdata/zoneinfo/America/Managua b/testdata/zoneinfo/America/Managua
new file mode 100644
index 0000000..86ef76b
Binary files /dev/null and b/testdata/zoneinfo/America/Managua differ
diff --git a/testdata/zoneinfo/America/Manaus b/testdata/zoneinfo/America/Manaus
new file mode 100644
index 0000000..59c952e
Binary files /dev/null and b/testdata/zoneinfo/America/Manaus differ
diff --git a/testdata/zoneinfo/America/Marigot b/testdata/zoneinfo/America/Marigot
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Marigot differ
diff --git a/testdata/zoneinfo/America/Martinique b/testdata/zoneinfo/America/Martinique
new file mode 100644
index 0000000..25c0232
Binary files /dev/null and b/testdata/zoneinfo/America/Martinique differ
diff --git a/testdata/zoneinfo/America/Matamoros b/testdata/zoneinfo/America/Matamoros
new file mode 100644
index 0000000..722751b
Binary files /dev/null and b/testdata/zoneinfo/America/Matamoros differ
diff --git a/testdata/zoneinfo/America/Mazatlan b/testdata/zoneinfo/America/Mazatlan
new file mode 100644
index 0000000..4c819fa
Binary files /dev/null and b/testdata/zoneinfo/America/Mazatlan differ
diff --git a/testdata/zoneinfo/America/Mendoza b/testdata/zoneinfo/America/Mendoza
new file mode 100644
index 0000000..691c569
Binary files /dev/null and b/testdata/zoneinfo/America/Mendoza differ
diff --git a/testdata/zoneinfo/America/Menominee b/testdata/zoneinfo/America/Menominee
new file mode 100644
index 0000000..28d2c56
Binary files /dev/null and b/testdata/zoneinfo/America/Menominee differ
diff --git a/testdata/zoneinfo/America/Merida b/testdata/zoneinfo/America/Merida
new file mode 100644
index 0000000..d3b0ca1
Binary files /dev/null and b/testdata/zoneinfo/America/Merida differ
diff --git a/testdata/zoneinfo/America/Metlakatla b/testdata/zoneinfo/America/Metlakatla
new file mode 100644
index 0000000..9fefee3
Binary files /dev/null and b/testdata/zoneinfo/America/Metlakatla differ
diff --git a/testdata/zoneinfo/America/Mexico_City b/testdata/zoneinfo/America/Mexico_City
new file mode 100644
index 0000000..ffcf8be
Binary files /dev/null and b/testdata/zoneinfo/America/Mexico_City differ
diff --git a/testdata/zoneinfo/America/Miquelon b/testdata/zoneinfo/America/Miquelon
new file mode 100644
index 0000000..3b62585
Binary files /dev/null and b/testdata/zoneinfo/America/Miquelon differ
diff --git a/testdata/zoneinfo/America/Moncton b/testdata/zoneinfo/America/Moncton
new file mode 100644
index 0000000..ecb69ef
Binary files /dev/null and b/testdata/zoneinfo/America/Moncton differ
diff --git a/testdata/zoneinfo/America/Monterrey b/testdata/zoneinfo/America/Monterrey
new file mode 100644
index 0000000..dea9e3f
Binary files /dev/null and b/testdata/zoneinfo/America/Monterrey differ
diff --git a/testdata/zoneinfo/America/Montevideo b/testdata/zoneinfo/America/Montevideo
new file mode 100644
index 0000000..4b2fb3e
Binary files /dev/null and b/testdata/zoneinfo/America/Montevideo differ
diff --git a/testdata/zoneinfo/America/Montreal b/testdata/zoneinfo/America/Montreal
new file mode 100644
index 0000000..fe6be8e
Binary files /dev/null and b/testdata/zoneinfo/America/Montreal differ
diff --git a/testdata/zoneinfo/America/Montserrat b/testdata/zoneinfo/America/Montserrat
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Montserrat differ
diff --git a/testdata/zoneinfo/America/Nassau b/testdata/zoneinfo/America/Nassau
new file mode 100644
index 0000000..fe6be8e
Binary files /dev/null and b/testdata/zoneinfo/America/Nassau differ
diff --git a/testdata/zoneinfo/America/New_York b/testdata/zoneinfo/America/New_York
new file mode 100644
index 0000000..2b6c2ee
Binary files /dev/null and b/testdata/zoneinfo/America/New_York differ
diff --git a/testdata/zoneinfo/America/Nipigon b/testdata/zoneinfo/America/Nipigon
new file mode 100644
index 0000000..b9f67a9
Binary files /dev/null and b/testdata/zoneinfo/America/Nipigon differ
diff --git a/testdata/zoneinfo/America/Nome b/testdata/zoneinfo/America/Nome
new file mode 100644
index 0000000..23ead1c
Binary files /dev/null and b/testdata/zoneinfo/America/Nome differ
diff --git a/testdata/zoneinfo/America/Noronha b/testdata/zoneinfo/America/Noronha
new file mode 100644
index 0000000..9e74745
Binary files /dev/null and b/testdata/zoneinfo/America/Noronha differ
diff --git a/testdata/zoneinfo/America/North_Dakota/Beulah b/testdata/zoneinfo/America/North_Dakota/Beulah
new file mode 100644
index 0000000..becf438
Binary files /dev/null and b/testdata/zoneinfo/America/North_Dakota/Beulah differ
diff --git a/testdata/zoneinfo/America/North_Dakota/Center b/testdata/zoneinfo/America/North_Dakota/Center
new file mode 100644
index 0000000..d03bda0
Binary files /dev/null and b/testdata/zoneinfo/America/North_Dakota/Center differ
diff --git a/testdata/zoneinfo/America/North_Dakota/New_Salem b/testdata/zoneinfo/America/North_Dakota/New_Salem
new file mode 100644
index 0000000..ecefc15
Binary files /dev/null and b/testdata/zoneinfo/America/North_Dakota/New_Salem differ
diff --git a/testdata/zoneinfo/America/Nuuk b/testdata/zoneinfo/America/Nuuk
new file mode 100644
index 0000000..4ddc99d
Binary files /dev/null and b/testdata/zoneinfo/America/Nuuk differ
diff --git a/testdata/zoneinfo/America/Ojinaga b/testdata/zoneinfo/America/Ojinaga
new file mode 100644
index 0000000..da0909c
Binary files /dev/null and b/testdata/zoneinfo/America/Ojinaga differ
diff --git a/testdata/zoneinfo/America/Panama b/testdata/zoneinfo/America/Panama
new file mode 100644
index 0000000..9154643
Binary files /dev/null and b/testdata/zoneinfo/America/Panama differ
diff --git a/testdata/zoneinfo/America/Pangnirtung b/testdata/zoneinfo/America/Pangnirtung
new file mode 100644
index 0000000..5be6f9b
Binary files /dev/null and b/testdata/zoneinfo/America/Pangnirtung differ
diff --git a/testdata/zoneinfo/America/Paramaribo b/testdata/zoneinfo/America/Paramaribo
new file mode 100644
index 0000000..24f925a
Binary files /dev/null and b/testdata/zoneinfo/America/Paramaribo differ
diff --git a/testdata/zoneinfo/America/Phoenix b/testdata/zoneinfo/America/Phoenix
new file mode 100644
index 0000000..c2bd2f9
Binary files /dev/null and b/testdata/zoneinfo/America/Phoenix differ
diff --git a/testdata/zoneinfo/America/Port-au-Prince b/testdata/zoneinfo/America/Port-au-Prince
new file mode 100644
index 0000000..3e75731
Binary files /dev/null and b/testdata/zoneinfo/America/Port-au-Prince differ
diff --git a/testdata/zoneinfo/America/Port_of_Spain b/testdata/zoneinfo/America/Port_of_Spain
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Port_of_Spain differ
diff --git a/testdata/zoneinfo/America/Porto_Acre b/testdata/zoneinfo/America/Porto_Acre
new file mode 100644
index 0000000..fb5185c
Binary files /dev/null and b/testdata/zoneinfo/America/Porto_Acre differ
diff --git a/testdata/zoneinfo/America/Porto_Velho b/testdata/zoneinfo/America/Porto_Velho
new file mode 100644
index 0000000..7f8047d
Binary files /dev/null and b/testdata/zoneinfo/America/Porto_Velho differ
diff --git a/testdata/zoneinfo/America/Puerto_Rico b/testdata/zoneinfo/America/Puerto_Rico
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Puerto_Rico differ
diff --git a/testdata/zoneinfo/America/Punta_Arenas b/testdata/zoneinfo/America/Punta_Arenas
new file mode 100644
index 0000000..c042104
Binary files /dev/null and b/testdata/zoneinfo/America/Punta_Arenas differ
diff --git a/testdata/zoneinfo/America/Rainy_River b/testdata/zoneinfo/America/Rainy_River
new file mode 100644
index 0000000..d6ddda4
Binary files /dev/null and b/testdata/zoneinfo/America/Rainy_River differ
diff --git a/testdata/zoneinfo/America/Rankin_Inlet b/testdata/zoneinfo/America/Rankin_Inlet
new file mode 100644
index 0000000..92e2ed2
Binary files /dev/null and b/testdata/zoneinfo/America/Rankin_Inlet differ
diff --git a/testdata/zoneinfo/America/Recife b/testdata/zoneinfo/America/Recife
new file mode 100644
index 0000000..305abcb
Binary files /dev/null and b/testdata/zoneinfo/America/Recife differ
diff --git a/testdata/zoneinfo/America/Regina b/testdata/zoneinfo/America/Regina
new file mode 100644
index 0000000..a3f8217
Binary files /dev/null and b/testdata/zoneinfo/America/Regina differ
diff --git a/testdata/zoneinfo/America/Resolute b/testdata/zoneinfo/America/Resolute
new file mode 100644
index 0000000..a84d1df
Binary files /dev/null and b/testdata/zoneinfo/America/Resolute differ
diff --git a/testdata/zoneinfo/America/Rio_Branco b/testdata/zoneinfo/America/Rio_Branco
new file mode 100644
index 0000000..fb5185c
Binary files /dev/null and b/testdata/zoneinfo/America/Rio_Branco differ
diff --git a/testdata/zoneinfo/America/Rosario b/testdata/zoneinfo/America/Rosario
new file mode 100644
index 0000000..35a52e5
Binary files /dev/null and b/testdata/zoneinfo/America/Rosario differ
diff --git a/testdata/zoneinfo/America/Santa_Isabel b/testdata/zoneinfo/America/Santa_Isabel
new file mode 100644
index 0000000..19ccd35
Binary files /dev/null and b/testdata/zoneinfo/America/Santa_Isabel differ
diff --git a/testdata/zoneinfo/America/Santarem b/testdata/zoneinfo/America/Santarem
new file mode 100644
index 0000000..f81d144
Binary files /dev/null and b/testdata/zoneinfo/America/Santarem differ
diff --git a/testdata/zoneinfo/America/Santiago b/testdata/zoneinfo/America/Santiago
new file mode 100644
index 0000000..cde8dbb
Binary files /dev/null and b/testdata/zoneinfo/America/Santiago differ
diff --git a/testdata/zoneinfo/America/Santo_Domingo b/testdata/zoneinfo/America/Santo_Domingo
new file mode 100644
index 0000000..3e07850
Binary files /dev/null and b/testdata/zoneinfo/America/Santo_Domingo differ
diff --git a/testdata/zoneinfo/America/Sao_Paulo b/testdata/zoneinfo/America/Sao_Paulo
new file mode 100644
index 0000000..a16da2c
Binary files /dev/null and b/testdata/zoneinfo/America/Sao_Paulo differ
diff --git a/testdata/zoneinfo/America/Scoresbysund b/testdata/zoneinfo/America/Scoresbysund
new file mode 100644
index 0000000..6db4912
Binary files /dev/null and b/testdata/zoneinfo/America/Scoresbysund differ
diff --git a/testdata/zoneinfo/America/Shiprock b/testdata/zoneinfo/America/Shiprock
new file mode 100644
index 0000000..09e54e5
Binary files /dev/null and b/testdata/zoneinfo/America/Shiprock differ
diff --git a/testdata/zoneinfo/America/Sitka b/testdata/zoneinfo/America/Sitka
new file mode 100644
index 0000000..36681ed
Binary files /dev/null and b/testdata/zoneinfo/America/Sitka differ
diff --git a/testdata/zoneinfo/America/St_Barthelemy b/testdata/zoneinfo/America/St_Barthelemy
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/St_Barthelemy differ
diff --git a/testdata/zoneinfo/America/St_Johns b/testdata/zoneinfo/America/St_Johns
new file mode 100644
index 0000000..e5f2aec
Binary files /dev/null and b/testdata/zoneinfo/America/St_Johns differ
diff --git a/testdata/zoneinfo/America/St_Kitts b/testdata/zoneinfo/America/St_Kitts
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/St_Kitts differ
diff --git a/testdata/zoneinfo/America/St_Lucia b/testdata/zoneinfo/America/St_Lucia
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/St_Lucia differ
diff --git a/testdata/zoneinfo/America/St_Thomas b/testdata/zoneinfo/America/St_Thomas
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/St_Thomas differ
diff --git a/testdata/zoneinfo/America/St_Vincent b/testdata/zoneinfo/America/St_Vincent
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/St_Vincent differ
diff --git a/testdata/zoneinfo/America/Swift_Current b/testdata/zoneinfo/America/Swift_Current
new file mode 100644
index 0000000..bdbb494
Binary files /dev/null and b/testdata/zoneinfo/America/Swift_Current differ
diff --git a/testdata/zoneinfo/America/Tegucigalpa b/testdata/zoneinfo/America/Tegucigalpa
new file mode 100644
index 0000000..38036a3
Binary files /dev/null and b/testdata/zoneinfo/America/Tegucigalpa differ
diff --git a/testdata/zoneinfo/America/Thule b/testdata/zoneinfo/America/Thule
new file mode 100644
index 0000000..f38dc56
Binary files /dev/null and b/testdata/zoneinfo/America/Thule differ
diff --git a/testdata/zoneinfo/America/Thunder_Bay b/testdata/zoneinfo/America/Thunder_Bay
new file mode 100644
index 0000000..fcb0328
Binary files /dev/null and b/testdata/zoneinfo/America/Thunder_Bay differ
diff --git a/testdata/zoneinfo/America/Tijuana b/testdata/zoneinfo/America/Tijuana
new file mode 100644
index 0000000..19ccd35
Binary files /dev/null and b/testdata/zoneinfo/America/Tijuana differ
diff --git a/testdata/zoneinfo/America/Toronto b/testdata/zoneinfo/America/Toronto
new file mode 100644
index 0000000..fe6be8e
Binary files /dev/null and b/testdata/zoneinfo/America/Toronto differ
diff --git a/testdata/zoneinfo/America/Tortola b/testdata/zoneinfo/America/Tortola
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Tortola differ
diff --git a/testdata/zoneinfo/America/Vancouver b/testdata/zoneinfo/America/Vancouver
new file mode 100644
index 0000000..c998491
Binary files /dev/null and b/testdata/zoneinfo/America/Vancouver differ
diff --git a/testdata/zoneinfo/America/Virgin b/testdata/zoneinfo/America/Virgin
new file mode 100644
index 0000000..47b4dc3
Binary files /dev/null and b/testdata/zoneinfo/America/Virgin differ
diff --git a/testdata/zoneinfo/America/Whitehorse b/testdata/zoneinfo/America/Whitehorse
new file mode 100644
index 0000000..878b6a9
Binary files /dev/null and b/testdata/zoneinfo/America/Whitehorse differ
diff --git a/testdata/zoneinfo/America/Winnipeg b/testdata/zoneinfo/America/Winnipeg
new file mode 100644
index 0000000..7e646d1
Binary files /dev/null and b/testdata/zoneinfo/America/Winnipeg differ
diff --git a/testdata/zoneinfo/America/Yakutat b/testdata/zoneinfo/America/Yakutat
new file mode 100644
index 0000000..773feba
Binary files /dev/null and b/testdata/zoneinfo/America/Yakutat differ
diff --git a/testdata/zoneinfo/America/Yellowknife b/testdata/zoneinfo/America/Yellowknife
new file mode 100644
index 0000000..c779cef
Binary files /dev/null and b/testdata/zoneinfo/America/Yellowknife differ
diff --git a/testdata/zoneinfo/Antarctica/Casey b/testdata/zoneinfo/Antarctica/Casey
new file mode 100644
index 0000000..30315cc
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Casey differ
diff --git a/testdata/zoneinfo/Antarctica/Davis b/testdata/zoneinfo/Antarctica/Davis
new file mode 100644
index 0000000..3ec3222
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Davis differ
diff --git a/testdata/zoneinfo/Antarctica/DumontDUrville b/testdata/zoneinfo/Antarctica/DumontDUrville
new file mode 100644
index 0000000..5d8fc3a
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/DumontDUrville differ
diff --git a/testdata/zoneinfo/Antarctica/Macquarie b/testdata/zoneinfo/Antarctica/Macquarie
new file mode 100644
index 0000000..3fc1f23
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Macquarie differ
diff --git a/testdata/zoneinfo/Antarctica/Mawson b/testdata/zoneinfo/Antarctica/Mawson
new file mode 100644
index 0000000..05e4c6c
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Mawson differ
diff --git a/testdata/zoneinfo/Antarctica/McMurdo b/testdata/zoneinfo/Antarctica/McMurdo
new file mode 100644
index 0000000..afb3929
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/McMurdo differ
diff --git a/testdata/zoneinfo/Antarctica/Palmer b/testdata/zoneinfo/Antarctica/Palmer
new file mode 100644
index 0000000..32c1941
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Palmer differ
diff --git a/testdata/zoneinfo/Antarctica/Rothera b/testdata/zoneinfo/Antarctica/Rothera
new file mode 100644
index 0000000..ea49c00
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Rothera differ
diff --git a/testdata/zoneinfo/Antarctica/South_Pole b/testdata/zoneinfo/Antarctica/South_Pole
new file mode 100644
index 0000000..afb3929
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/South_Pole differ
diff --git a/testdata/zoneinfo/Antarctica/Syowa b/testdata/zoneinfo/Antarctica/Syowa
new file mode 100644
index 0000000..01c47cc
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Syowa differ
diff --git a/testdata/zoneinfo/Antarctica/Troll b/testdata/zoneinfo/Antarctica/Troll
new file mode 100644
index 0000000..4e31aff
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Troll differ
diff --git a/testdata/zoneinfo/Antarctica/Vostok b/testdata/zoneinfo/Antarctica/Vostok
new file mode 100644
index 0000000..6e32907
Binary files /dev/null and b/testdata/zoneinfo/Antarctica/Vostok differ
diff --git a/testdata/zoneinfo/Arctic/Longyearbyen b/testdata/zoneinfo/Arctic/Longyearbyen
new file mode 100644
index 0000000..dfc5095
Binary files /dev/null and b/testdata/zoneinfo/Arctic/Longyearbyen differ
diff --git a/testdata/zoneinfo/Asia/Aden b/testdata/zoneinfo/Asia/Aden
new file mode 100644
index 0000000..01c47cc
Binary files /dev/null and b/testdata/zoneinfo/Asia/Aden differ
diff --git a/testdata/zoneinfo/Asia/Almaty b/testdata/zoneinfo/Asia/Almaty
new file mode 100644
index 0000000..3ec4fc8
Binary files /dev/null and b/testdata/zoneinfo/Asia/Almaty differ
diff --git a/testdata/zoneinfo/Asia/Amman b/testdata/zoneinfo/Asia/Amman
new file mode 100644
index 0000000..d97d308
Binary files /dev/null and b/testdata/zoneinfo/Asia/Amman differ
diff --git a/testdata/zoneinfo/Asia/Anadyr b/testdata/zoneinfo/Asia/Anadyr
new file mode 100644
index 0000000..551884d
Binary files /dev/null and b/testdata/zoneinfo/Asia/Anadyr differ
diff --git a/testdata/zoneinfo/Asia/Aqtau b/testdata/zoneinfo/Asia/Aqtau
new file mode 100644
index 0000000..3a40d11
Binary files /dev/null and b/testdata/zoneinfo/Asia/Aqtau differ
diff --git a/testdata/zoneinfo/Asia/Aqtobe b/testdata/zoneinfo/Asia/Aqtobe
new file mode 100644
index 0000000..62c5840
Binary files /dev/null and b/testdata/zoneinfo/Asia/Aqtobe differ
diff --git a/testdata/zoneinfo/Asia/Ashgabat b/testdata/zoneinfo/Asia/Ashgabat
new file mode 100644
index 0000000..8482167
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ashgabat differ
diff --git a/testdata/zoneinfo/Asia/Ashkhabad b/testdata/zoneinfo/Asia/Ashkhabad
new file mode 100644
index 0000000..8482167
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ashkhabad differ
diff --git a/testdata/zoneinfo/Asia/Atyrau b/testdata/zoneinfo/Asia/Atyrau
new file mode 100644
index 0000000..cb2c82f
Binary files /dev/null and b/testdata/zoneinfo/Asia/Atyrau differ
diff --git a/testdata/zoneinfo/Asia/Baghdad b/testdata/zoneinfo/Asia/Baghdad
new file mode 100644
index 0000000..a3ce975
Binary files /dev/null and b/testdata/zoneinfo/Asia/Baghdad differ
diff --git a/testdata/zoneinfo/Asia/Bahrain b/testdata/zoneinfo/Asia/Bahrain
new file mode 100644
index 0000000..7409d74
Binary files /dev/null and b/testdata/zoneinfo/Asia/Bahrain differ
diff --git a/testdata/zoneinfo/Asia/Baku b/testdata/zoneinfo/Asia/Baku
new file mode 100644
index 0000000..96203d7
Binary files /dev/null and b/testdata/zoneinfo/Asia/Baku differ
diff --git a/testdata/zoneinfo/Asia/Bangkok b/testdata/zoneinfo/Asia/Bangkok
new file mode 100644
index 0000000..ed687d2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Bangkok differ
diff --git a/testdata/zoneinfo/Asia/Barnaul b/testdata/zoneinfo/Asia/Barnaul
new file mode 100644
index 0000000..ff976dd
Binary files /dev/null and b/testdata/zoneinfo/Asia/Barnaul differ
diff --git a/testdata/zoneinfo/Asia/Beirut b/testdata/zoneinfo/Asia/Beirut
new file mode 100644
index 0000000..55dce57
Binary files /dev/null and b/testdata/zoneinfo/Asia/Beirut differ
diff --git a/testdata/zoneinfo/Asia/Bishkek b/testdata/zoneinfo/Asia/Bishkek
new file mode 100644
index 0000000..fe7832c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Bishkek differ
diff --git a/testdata/zoneinfo/Asia/Brunei b/testdata/zoneinfo/Asia/Brunei
new file mode 100644
index 0000000..e67b411
Binary files /dev/null and b/testdata/zoneinfo/Asia/Brunei differ
diff --git a/testdata/zoneinfo/Asia/Calcutta b/testdata/zoneinfo/Asia/Calcutta
new file mode 100644
index 0000000..00bc80a
Binary files /dev/null and b/testdata/zoneinfo/Asia/Calcutta differ
diff --git a/testdata/zoneinfo/Asia/Chita b/testdata/zoneinfo/Asia/Chita
new file mode 100644
index 0000000..9d49cd3
Binary files /dev/null and b/testdata/zoneinfo/Asia/Chita differ
diff --git a/testdata/zoneinfo/Asia/Choibalsan b/testdata/zoneinfo/Asia/Choibalsan
new file mode 100644
index 0000000..0a948c2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Choibalsan differ
diff --git a/testdata/zoneinfo/Asia/Chongqing b/testdata/zoneinfo/Asia/Chongqing
new file mode 100644
index 0000000..d6b6698
Binary files /dev/null and b/testdata/zoneinfo/Asia/Chongqing differ
diff --git a/testdata/zoneinfo/Asia/Chungking b/testdata/zoneinfo/Asia/Chungking
new file mode 100644
index 0000000..d6b6698
Binary files /dev/null and b/testdata/zoneinfo/Asia/Chungking differ
diff --git a/testdata/zoneinfo/Asia/Colombo b/testdata/zoneinfo/Asia/Colombo
new file mode 100644
index 0000000..3eeb1b7
Binary files /dev/null and b/testdata/zoneinfo/Asia/Colombo differ
diff --git a/testdata/zoneinfo/Asia/Dacca b/testdata/zoneinfo/Asia/Dacca
new file mode 100644
index 0000000..2813680
Binary files /dev/null and b/testdata/zoneinfo/Asia/Dacca differ
diff --git a/testdata/zoneinfo/Asia/Damascus b/testdata/zoneinfo/Asia/Damascus
new file mode 100644
index 0000000..168ef9b
Binary files /dev/null and b/testdata/zoneinfo/Asia/Damascus differ
diff --git a/testdata/zoneinfo/Asia/Dhaka b/testdata/zoneinfo/Asia/Dhaka
new file mode 100644
index 0000000..2813680
Binary files /dev/null and b/testdata/zoneinfo/Asia/Dhaka differ
diff --git a/testdata/zoneinfo/Asia/Dili b/testdata/zoneinfo/Asia/Dili
new file mode 100644
index 0000000..bb7be9f
Binary files /dev/null and b/testdata/zoneinfo/Asia/Dili differ
diff --git a/testdata/zoneinfo/Asia/Dubai b/testdata/zoneinfo/Asia/Dubai
new file mode 100644
index 0000000..58d75bc
Binary files /dev/null and b/testdata/zoneinfo/Asia/Dubai differ
diff --git a/testdata/zoneinfo/Asia/Dushanbe b/testdata/zoneinfo/Asia/Dushanbe
new file mode 100644
index 0000000..d83fb07
Binary files /dev/null and b/testdata/zoneinfo/Asia/Dushanbe differ
diff --git a/testdata/zoneinfo/Asia/Famagusta b/testdata/zoneinfo/Asia/Famagusta
new file mode 100644
index 0000000..cc44179
Binary files /dev/null and b/testdata/zoneinfo/Asia/Famagusta differ
diff --git a/testdata/zoneinfo/Asia/Gaza b/testdata/zoneinfo/Asia/Gaza
new file mode 100644
index 0000000..effc4df
Binary files /dev/null and b/testdata/zoneinfo/Asia/Gaza differ
diff --git a/testdata/zoneinfo/Asia/Harbin b/testdata/zoneinfo/Asia/Harbin
new file mode 100644
index 0000000..d6b6698
Binary files /dev/null and b/testdata/zoneinfo/Asia/Harbin differ
diff --git a/testdata/zoneinfo/Asia/Hebron b/testdata/zoneinfo/Asia/Hebron
new file mode 100644
index 0000000..aa52bd2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Hebron differ
diff --git a/testdata/zoneinfo/Asia/Ho_Chi_Minh b/testdata/zoneinfo/Asia/Ho_Chi_Minh
new file mode 100644
index 0000000..7ca9972
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ho_Chi_Minh differ
diff --git a/testdata/zoneinfo/Asia/Hong_Kong b/testdata/zoneinfo/Asia/Hong_Kong
new file mode 100644
index 0000000..c80e364
Binary files /dev/null and b/testdata/zoneinfo/Asia/Hong_Kong differ
diff --git a/testdata/zoneinfo/Asia/Hovd b/testdata/zoneinfo/Asia/Hovd
new file mode 100644
index 0000000..6e08a26
Binary files /dev/null and b/testdata/zoneinfo/Asia/Hovd differ
diff --git a/testdata/zoneinfo/Asia/Irkutsk b/testdata/zoneinfo/Asia/Irkutsk
new file mode 100644
index 0000000..550e2a0
Binary files /dev/null and b/testdata/zoneinfo/Asia/Irkutsk differ
diff --git a/testdata/zoneinfo/Asia/Istanbul b/testdata/zoneinfo/Asia/Istanbul
new file mode 100644
index 0000000..c891866
Binary files /dev/null and b/testdata/zoneinfo/Asia/Istanbul differ
diff --git a/testdata/zoneinfo/Asia/Jakarta b/testdata/zoneinfo/Asia/Jakarta
new file mode 100644
index 0000000..c9752d2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Jakarta differ
diff --git a/testdata/zoneinfo/Asia/Jayapura b/testdata/zoneinfo/Asia/Jayapura
new file mode 100644
index 0000000..7c22f53
Binary files /dev/null and b/testdata/zoneinfo/Asia/Jayapura differ
diff --git a/testdata/zoneinfo/Asia/Jerusalem b/testdata/zoneinfo/Asia/Jerusalem
new file mode 100644
index 0000000..4c49bbf
Binary files /dev/null and b/testdata/zoneinfo/Asia/Jerusalem differ
diff --git a/testdata/zoneinfo/Asia/Kabul b/testdata/zoneinfo/Asia/Kabul
new file mode 100644
index 0000000..660ce4c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kabul differ
diff --git a/testdata/zoneinfo/Asia/Kamchatka b/testdata/zoneinfo/Asia/Kamchatka
new file mode 100644
index 0000000..c651554
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kamchatka differ
diff --git a/testdata/zoneinfo/Asia/Karachi b/testdata/zoneinfo/Asia/Karachi
new file mode 100644
index 0000000..e56d5af
Binary files /dev/null and b/testdata/zoneinfo/Asia/Karachi differ
diff --git a/testdata/zoneinfo/Asia/Kashgar b/testdata/zoneinfo/Asia/Kashgar
new file mode 100644
index 0000000..69ff7f6
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kashgar differ
diff --git a/testdata/zoneinfo/Asia/Kathmandu b/testdata/zoneinfo/Asia/Kathmandu
new file mode 100644
index 0000000..3a0d330
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kathmandu differ
diff --git a/testdata/zoneinfo/Asia/Katmandu b/testdata/zoneinfo/Asia/Katmandu
new file mode 100644
index 0000000..3a0d330
Binary files /dev/null and b/testdata/zoneinfo/Asia/Katmandu differ
diff --git a/testdata/zoneinfo/Asia/Khandyga b/testdata/zoneinfo/Asia/Khandyga
new file mode 100644
index 0000000..aeb7332
Binary files /dev/null and b/testdata/zoneinfo/Asia/Khandyga differ
diff --git a/testdata/zoneinfo/Asia/Kolkata b/testdata/zoneinfo/Asia/Kolkata
new file mode 100644
index 0000000..00bc80a
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kolkata differ
diff --git a/testdata/zoneinfo/Asia/Krasnoyarsk b/testdata/zoneinfo/Asia/Krasnoyarsk
new file mode 100644
index 0000000..e0d4fcb
Binary files /dev/null and b/testdata/zoneinfo/Asia/Krasnoyarsk differ
diff --git a/testdata/zoneinfo/Asia/Kuala_Lumpur b/testdata/zoneinfo/Asia/Kuala_Lumpur
new file mode 100644
index 0000000..e93dd51
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kuala_Lumpur differ
diff --git a/testdata/zoneinfo/Asia/Kuching b/testdata/zoneinfo/Asia/Kuching
new file mode 100644
index 0000000..59bc6e4
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kuching differ
diff --git a/testdata/zoneinfo/Asia/Kuwait b/testdata/zoneinfo/Asia/Kuwait
new file mode 100644
index 0000000..01c47cc
Binary files /dev/null and b/testdata/zoneinfo/Asia/Kuwait differ
diff --git a/testdata/zoneinfo/Asia/Macao b/testdata/zoneinfo/Asia/Macao
new file mode 100644
index 0000000..c22f75e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Macao differ
diff --git a/testdata/zoneinfo/Asia/Macau b/testdata/zoneinfo/Asia/Macau
new file mode 100644
index 0000000..c22f75e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Macau differ
diff --git a/testdata/zoneinfo/Asia/Magadan b/testdata/zoneinfo/Asia/Magadan
new file mode 100644
index 0000000..16bac84
Binary files /dev/null and b/testdata/zoneinfo/Asia/Magadan differ
diff --git a/testdata/zoneinfo/Asia/Makassar b/testdata/zoneinfo/Asia/Makassar
new file mode 100644
index 0000000..5990010
Binary files /dev/null and b/testdata/zoneinfo/Asia/Makassar differ
diff --git a/testdata/zoneinfo/Asia/Manila b/testdata/zoneinfo/Asia/Manila
new file mode 100644
index 0000000..3c3584e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Manila differ
diff --git a/testdata/zoneinfo/Asia/Muscat b/testdata/zoneinfo/Asia/Muscat
new file mode 100644
index 0000000..58d75bc
Binary files /dev/null and b/testdata/zoneinfo/Asia/Muscat differ
diff --git a/testdata/zoneinfo/Asia/Nicosia b/testdata/zoneinfo/Asia/Nicosia
new file mode 100644
index 0000000..c210d0a
Binary files /dev/null and b/testdata/zoneinfo/Asia/Nicosia differ
diff --git a/testdata/zoneinfo/Asia/Novokuznetsk b/testdata/zoneinfo/Asia/Novokuznetsk
new file mode 100644
index 0000000..9378d50
Binary files /dev/null and b/testdata/zoneinfo/Asia/Novokuznetsk differ
diff --git a/testdata/zoneinfo/Asia/Novosibirsk b/testdata/zoneinfo/Asia/Novosibirsk
new file mode 100644
index 0000000..65a9fa2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Novosibirsk differ
diff --git a/testdata/zoneinfo/Asia/Omsk b/testdata/zoneinfo/Asia/Omsk
new file mode 100644
index 0000000..dc0ed42
Binary files /dev/null and b/testdata/zoneinfo/Asia/Omsk differ
diff --git a/testdata/zoneinfo/Asia/Oral b/testdata/zoneinfo/Asia/Oral
new file mode 100644
index 0000000..25a63ec
Binary files /dev/null and b/testdata/zoneinfo/Asia/Oral differ
diff --git a/testdata/zoneinfo/Asia/Phnom_Penh b/testdata/zoneinfo/Asia/Phnom_Penh
new file mode 100644
index 0000000..ed687d2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Phnom_Penh differ
diff --git a/testdata/zoneinfo/Asia/Pontianak b/testdata/zoneinfo/Asia/Pontianak
new file mode 100644
index 0000000..285bed2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Pontianak differ
diff --git a/testdata/zoneinfo/Asia/Pyongyang b/testdata/zoneinfo/Asia/Pyongyang
new file mode 100644
index 0000000..57240cf
Binary files /dev/null and b/testdata/zoneinfo/Asia/Pyongyang differ
diff --git a/testdata/zoneinfo/Asia/Qatar b/testdata/zoneinfo/Asia/Qatar
new file mode 100644
index 0000000..7409d74
Binary files /dev/null and b/testdata/zoneinfo/Asia/Qatar differ
diff --git a/testdata/zoneinfo/Asia/Qostanay b/testdata/zoneinfo/Asia/Qostanay
new file mode 100644
index 0000000..ff6fe61
Binary files /dev/null and b/testdata/zoneinfo/Asia/Qostanay differ
diff --git a/testdata/zoneinfo/Asia/Qyzylorda b/testdata/zoneinfo/Asia/Qyzylorda
new file mode 100644
index 0000000..fe4d6c6
Binary files /dev/null and b/testdata/zoneinfo/Asia/Qyzylorda differ
diff --git a/testdata/zoneinfo/Asia/Rangoon b/testdata/zoneinfo/Asia/Rangoon
new file mode 100644
index 0000000..14b2ad0
Binary files /dev/null and b/testdata/zoneinfo/Asia/Rangoon differ
diff --git a/testdata/zoneinfo/Asia/Riyadh b/testdata/zoneinfo/Asia/Riyadh
new file mode 100644
index 0000000..01c47cc
Binary files /dev/null and b/testdata/zoneinfo/Asia/Riyadh differ
diff --git a/testdata/zoneinfo/Asia/Saigon b/testdata/zoneinfo/Asia/Saigon
new file mode 100644
index 0000000..7ca9972
Binary files /dev/null and b/testdata/zoneinfo/Asia/Saigon differ
diff --git a/testdata/zoneinfo/Asia/Sakhalin b/testdata/zoneinfo/Asia/Sakhalin
new file mode 100644
index 0000000..69f0faa
Binary files /dev/null and b/testdata/zoneinfo/Asia/Sakhalin differ
diff --git a/testdata/zoneinfo/Asia/Samarkand b/testdata/zoneinfo/Asia/Samarkand
new file mode 100644
index 0000000..c43e27c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Samarkand differ
diff --git a/testdata/zoneinfo/Asia/Seoul b/testdata/zoneinfo/Asia/Seoul
new file mode 100644
index 0000000..1755147
Binary files /dev/null and b/testdata/zoneinfo/Asia/Seoul differ
diff --git a/testdata/zoneinfo/Asia/Shanghai b/testdata/zoneinfo/Asia/Shanghai
new file mode 100644
index 0000000..d6b6698
Binary files /dev/null and b/testdata/zoneinfo/Asia/Shanghai differ
diff --git a/testdata/zoneinfo/Asia/Singapore b/testdata/zoneinfo/Asia/Singapore
new file mode 100644
index 0000000..350d77e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Singapore differ
diff --git a/testdata/zoneinfo/Asia/Srednekolymsk b/testdata/zoneinfo/Asia/Srednekolymsk
new file mode 100644
index 0000000..7fdee5c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Srednekolymsk differ
diff --git a/testdata/zoneinfo/Asia/Taipei b/testdata/zoneinfo/Asia/Taipei
new file mode 100644
index 0000000..35d89d0
Binary files /dev/null and b/testdata/zoneinfo/Asia/Taipei differ
diff --git a/testdata/zoneinfo/Asia/Tashkent b/testdata/zoneinfo/Asia/Tashkent
new file mode 100644
index 0000000..65ee428
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tashkent differ
diff --git a/testdata/zoneinfo/Asia/Tbilisi b/testdata/zoneinfo/Asia/Tbilisi
new file mode 100644
index 0000000..166e434
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tbilisi differ
diff --git a/testdata/zoneinfo/Asia/Tehran b/testdata/zoneinfo/Asia/Tehran
new file mode 100644
index 0000000..f1555f0
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tehran differ
diff --git a/testdata/zoneinfo/Asia/Tel_Aviv b/testdata/zoneinfo/Asia/Tel_Aviv
new file mode 100644
index 0000000..4c49bbf
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tel_Aviv differ
diff --git a/testdata/zoneinfo/Asia/Thimbu b/testdata/zoneinfo/Asia/Thimbu
new file mode 100644
index 0000000..0edc72c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Thimbu differ
diff --git a/testdata/zoneinfo/Asia/Thimphu b/testdata/zoneinfo/Asia/Thimphu
new file mode 100644
index 0000000..0edc72c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Thimphu differ
diff --git a/testdata/zoneinfo/Asia/Tokyo b/testdata/zoneinfo/Asia/Tokyo
new file mode 100644
index 0000000..1aa066c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tokyo differ
diff --git a/testdata/zoneinfo/Asia/Tomsk b/testdata/zoneinfo/Asia/Tomsk
new file mode 100644
index 0000000..c3c307d
Binary files /dev/null and b/testdata/zoneinfo/Asia/Tomsk differ
diff --git a/testdata/zoneinfo/Asia/Ujung_Pandang b/testdata/zoneinfo/Asia/Ujung_Pandang
new file mode 100644
index 0000000..5990010
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ujung_Pandang differ
diff --git a/testdata/zoneinfo/Asia/Ulaanbaatar b/testdata/zoneinfo/Asia/Ulaanbaatar
new file mode 100644
index 0000000..6f5d3a1
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ulaanbaatar differ
diff --git a/testdata/zoneinfo/Asia/Ulan_Bator b/testdata/zoneinfo/Asia/Ulan_Bator
new file mode 100644
index 0000000..6f5d3a1
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ulan_Bator differ
diff --git a/testdata/zoneinfo/Asia/Urumqi b/testdata/zoneinfo/Asia/Urumqi
new file mode 100644
index 0000000..69ff7f6
Binary files /dev/null and b/testdata/zoneinfo/Asia/Urumqi differ
diff --git a/testdata/zoneinfo/Asia/Ust-Nera b/testdata/zoneinfo/Asia/Ust-Nera
new file mode 100644
index 0000000..c39331e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Ust-Nera differ
diff --git a/testdata/zoneinfo/Asia/Vientiane b/testdata/zoneinfo/Asia/Vientiane
new file mode 100644
index 0000000..ed687d2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Vientiane differ
diff --git a/testdata/zoneinfo/Asia/Vladivostok b/testdata/zoneinfo/Asia/Vladivostok
new file mode 100644
index 0000000..72a3d4e
Binary files /dev/null and b/testdata/zoneinfo/Asia/Vladivostok differ
diff --git a/testdata/zoneinfo/Asia/Yakutsk b/testdata/zoneinfo/Asia/Yakutsk
new file mode 100644
index 0000000..336f932
Binary files /dev/null and b/testdata/zoneinfo/Asia/Yakutsk differ
diff --git a/testdata/zoneinfo/Asia/Yangon b/testdata/zoneinfo/Asia/Yangon
new file mode 100644
index 0000000..14b2ad0
Binary files /dev/null and b/testdata/zoneinfo/Asia/Yangon differ
diff --git a/testdata/zoneinfo/Asia/Yekaterinburg b/testdata/zoneinfo/Asia/Yekaterinburg
new file mode 100644
index 0000000..a3bf7f2
Binary files /dev/null and b/testdata/zoneinfo/Asia/Yekaterinburg differ
diff --git a/testdata/zoneinfo/Asia/Yerevan b/testdata/zoneinfo/Asia/Yerevan
new file mode 100644
index 0000000..6dd927c
Binary files /dev/null and b/testdata/zoneinfo/Asia/Yerevan differ
diff --git a/testdata/zoneinfo/Atlantic/Azores b/testdata/zoneinfo/Atlantic/Azores
new file mode 100644
index 0000000..e6e2616
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Azores differ
diff --git a/testdata/zoneinfo/Atlantic/Bermuda b/testdata/zoneinfo/Atlantic/Bermuda
new file mode 100644
index 0000000..abc75ea
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Bermuda differ
diff --git a/testdata/zoneinfo/Atlantic/Canary b/testdata/zoneinfo/Atlantic/Canary
new file mode 100644
index 0000000..5ab3243
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Canary differ
diff --git a/testdata/zoneinfo/Atlantic/Cape_Verde b/testdata/zoneinfo/Atlantic/Cape_Verde
new file mode 100644
index 0000000..8f7de1c
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Cape_Verde differ
diff --git a/testdata/zoneinfo/Atlantic/Faeroe b/testdata/zoneinfo/Atlantic/Faeroe
new file mode 100644
index 0000000..9558bf7
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Faeroe differ
diff --git a/testdata/zoneinfo/Atlantic/Faroe b/testdata/zoneinfo/Atlantic/Faroe
new file mode 100644
index 0000000..9558bf7
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Faroe differ
diff --git a/testdata/zoneinfo/Atlantic/Jan_Mayen b/testdata/zoneinfo/Atlantic/Jan_Mayen
new file mode 100644
index 0000000..dfc5095
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Jan_Mayen differ
diff --git a/testdata/zoneinfo/Atlantic/Madeira b/testdata/zoneinfo/Atlantic/Madeira
new file mode 100644
index 0000000..cf965c3
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Madeira differ
diff --git a/testdata/zoneinfo/Atlantic/Reykjavik b/testdata/zoneinfo/Atlantic/Reykjavik
new file mode 100644
index 0000000..2451aca
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Reykjavik differ
diff --git a/testdata/zoneinfo/Atlantic/South_Georgia b/testdata/zoneinfo/Atlantic/South_Georgia
new file mode 100644
index 0000000..7fa5f46
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/South_Georgia differ
diff --git a/testdata/zoneinfo/Atlantic/St_Helena b/testdata/zoneinfo/Atlantic/St_Helena
new file mode 100644
index 0000000..8906e88
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/St_Helena differ
diff --git a/testdata/zoneinfo/Atlantic/Stanley b/testdata/zoneinfo/Atlantic/Stanley
new file mode 100644
index 0000000..1a4c8ea
Binary files /dev/null and b/testdata/zoneinfo/Atlantic/Stanley differ
diff --git a/testdata/zoneinfo/Australia/ACT b/testdata/zoneinfo/Australia/ACT
new file mode 100644
index 0000000..1975a3a
Binary files /dev/null and b/testdata/zoneinfo/Australia/ACT differ
diff --git a/testdata/zoneinfo/Australia/Adelaide b/testdata/zoneinfo/Australia/Adelaide
new file mode 100644
index 0000000..3bfbbc5
Binary files /dev/null and b/testdata/zoneinfo/Australia/Adelaide differ
diff --git a/testdata/zoneinfo/Australia/Brisbane b/testdata/zoneinfo/Australia/Brisbane
new file mode 100644
index 0000000..dc9a980
Binary files /dev/null and b/testdata/zoneinfo/Australia/Brisbane differ
diff --git a/testdata/zoneinfo/Australia/Broken_Hill b/testdata/zoneinfo/Australia/Broken_Hill
new file mode 100644
index 0000000..947b509
Binary files /dev/null and b/testdata/zoneinfo/Australia/Broken_Hill differ
diff --git a/testdata/zoneinfo/Australia/Canberra b/testdata/zoneinfo/Australia/Canberra
new file mode 100644
index 0000000..1975a3a
Binary files /dev/null and b/testdata/zoneinfo/Australia/Canberra differ
diff --git a/testdata/zoneinfo/Australia/Currie b/testdata/zoneinfo/Australia/Currie
new file mode 100644
index 0000000..dc2ef55
Binary files /dev/null and b/testdata/zoneinfo/Australia/Currie differ
diff --git a/testdata/zoneinfo/Australia/Darwin b/testdata/zoneinfo/Australia/Darwin
new file mode 100644
index 0000000..a6a6730
Binary files /dev/null and b/testdata/zoneinfo/Australia/Darwin differ
diff --git a/testdata/zoneinfo/Australia/Eucla b/testdata/zoneinfo/Australia/Eucla
new file mode 100644
index 0000000..9080f5c
Binary files /dev/null and b/testdata/zoneinfo/Australia/Eucla differ
diff --git a/testdata/zoneinfo/Australia/Hobart b/testdata/zoneinfo/Australia/Hobart
new file mode 100644
index 0000000..dc2ef55
Binary files /dev/null and b/testdata/zoneinfo/Australia/Hobart differ
diff --git a/testdata/zoneinfo/Australia/LHI b/testdata/zoneinfo/Australia/LHI
new file mode 100644
index 0000000..4d4ec8c
Binary files /dev/null and b/testdata/zoneinfo/Australia/LHI differ
diff --git a/testdata/zoneinfo/Australia/Lindeman b/testdata/zoneinfo/Australia/Lindeman
new file mode 100644
index 0000000..131d77b
Binary files /dev/null and b/testdata/zoneinfo/Australia/Lindeman differ
diff --git a/testdata/zoneinfo/Australia/Lord_Howe b/testdata/zoneinfo/Australia/Lord_Howe
new file mode 100644
index 0000000..4d4ec8c
Binary files /dev/null and b/testdata/zoneinfo/Australia/Lord_Howe differ
diff --git a/testdata/zoneinfo/Australia/Melbourne b/testdata/zoneinfo/Australia/Melbourne
new file mode 100644
index 0000000..d3f195a
Binary files /dev/null and b/testdata/zoneinfo/Australia/Melbourne differ
diff --git a/testdata/zoneinfo/Australia/NSW b/testdata/zoneinfo/Australia/NSW
new file mode 100644
index 0000000..1975a3a
Binary files /dev/null and b/testdata/zoneinfo/Australia/NSW differ
diff --git a/testdata/zoneinfo/Australia/North b/testdata/zoneinfo/Australia/North
new file mode 100644
index 0000000..a6a6730
Binary files /dev/null and b/testdata/zoneinfo/Australia/North differ
diff --git a/testdata/zoneinfo/Australia/Perth b/testdata/zoneinfo/Australia/Perth
new file mode 100644
index 0000000..4f77182
Binary files /dev/null and b/testdata/zoneinfo/Australia/Perth differ
diff --git a/testdata/zoneinfo/Australia/Queensland b/testdata/zoneinfo/Australia/Queensland
new file mode 100644
index 0000000..dc9a980
Binary files /dev/null and b/testdata/zoneinfo/Australia/Queensland differ
diff --git a/testdata/zoneinfo/Australia/South b/testdata/zoneinfo/Australia/South
new file mode 100644
index 0000000..3bfbbc5
Binary files /dev/null and b/testdata/zoneinfo/Australia/South differ
diff --git a/testdata/zoneinfo/Australia/Sydney b/testdata/zoneinfo/Australia/Sydney
new file mode 100644
index 0000000..1975a3a
Binary files /dev/null and b/testdata/zoneinfo/Australia/Sydney differ
diff --git a/testdata/zoneinfo/Australia/Tasmania b/testdata/zoneinfo/Australia/Tasmania
new file mode 100644
index 0000000..dc2ef55
Binary files /dev/null and b/testdata/zoneinfo/Australia/Tasmania differ
diff --git a/testdata/zoneinfo/Australia/Victoria b/testdata/zoneinfo/Australia/Victoria
new file mode 100644
index 0000000..d3f195a
Binary files /dev/null and b/testdata/zoneinfo/Australia/Victoria differ
diff --git a/testdata/zoneinfo/Australia/West b/testdata/zoneinfo/Australia/West
new file mode 100644
index 0000000..4f77182
Binary files /dev/null and b/testdata/zoneinfo/Australia/West differ
diff --git a/testdata/zoneinfo/Australia/Yancowinna b/testdata/zoneinfo/Australia/Yancowinna
new file mode 100644
index 0000000..947b509
Binary files /dev/null and b/testdata/zoneinfo/Australia/Yancowinna differ
diff --git a/testdata/zoneinfo/Brazil/Acre b/testdata/zoneinfo/Brazil/Acre
new file mode 100644
index 0000000..fb5185c
Binary files /dev/null and b/testdata/zoneinfo/Brazil/Acre differ
diff --git a/testdata/zoneinfo/Brazil/DeNoronha b/testdata/zoneinfo/Brazil/DeNoronha
new file mode 100644
index 0000000..9e74745
Binary files /dev/null and b/testdata/zoneinfo/Brazil/DeNoronha differ
diff --git a/testdata/zoneinfo/Brazil/East b/testdata/zoneinfo/Brazil/East
new file mode 100644
index 0000000..a16da2c
Binary files /dev/null and b/testdata/zoneinfo/Brazil/East differ
diff --git a/testdata/zoneinfo/Brazil/West b/testdata/zoneinfo/Brazil/West
new file mode 100644
index 0000000..59c952e
Binary files /dev/null and b/testdata/zoneinfo/Brazil/West differ
diff --git a/testdata/zoneinfo/CET b/testdata/zoneinfo/CET
new file mode 100644
index 0000000..546748d
Binary files /dev/null and b/testdata/zoneinfo/CET differ
diff --git a/testdata/zoneinfo/CST6CDT b/testdata/zoneinfo/CST6CDT
new file mode 100644
index 0000000..d931558
Binary files /dev/null and b/testdata/zoneinfo/CST6CDT differ
diff --git a/testdata/zoneinfo/Canada/Atlantic b/testdata/zoneinfo/Canada/Atlantic
new file mode 100644
index 0000000..9fa850a
Binary files /dev/null and b/testdata/zoneinfo/Canada/Atlantic differ
diff --git a/testdata/zoneinfo/Canada/Central b/testdata/zoneinfo/Canada/Central
new file mode 100644
index 0000000..7e646d1
Binary files /dev/null and b/testdata/zoneinfo/Canada/Central differ
diff --git a/testdata/zoneinfo/Canada/Eastern b/testdata/zoneinfo/Canada/Eastern
new file mode 100644
index 0000000..fe6be8e
Binary files /dev/null and b/testdata/zoneinfo/Canada/Eastern differ
diff --git a/testdata/zoneinfo/Canada/Mountain b/testdata/zoneinfo/Canada/Mountain
new file mode 100644
index 0000000..645ee94
Binary files /dev/null and b/testdata/zoneinfo/Canada/Mountain differ
diff --git a/testdata/zoneinfo/Canada/Newfoundland b/testdata/zoneinfo/Canada/Newfoundland
new file mode 100644
index 0000000..e5f2aec
Binary files /dev/null and b/testdata/zoneinfo/Canada/Newfoundland differ
diff --git a/testdata/zoneinfo/Canada/Pacific b/testdata/zoneinfo/Canada/Pacific
new file mode 100644
index 0000000..c998491
Binary files /dev/null and b/testdata/zoneinfo/Canada/Pacific differ
diff --git a/testdata/zoneinfo/Canada/Saskatchewan b/testdata/zoneinfo/Canada/Saskatchewan
new file mode 100644
index 0000000..a3f8217
Binary files /dev/null and b/testdata/zoneinfo/Canada/Saskatchewan differ
diff --git a/testdata/zoneinfo/Canada/Yukon b/testdata/zoneinfo/Canada/Yukon
new file mode 100644
index 0000000..878b6a9
Binary files /dev/null and b/testdata/zoneinfo/Canada/Yukon differ
diff --git a/testdata/zoneinfo/Chile/Continental b/testdata/zoneinfo/Chile/Continental
new file mode 100644
index 0000000..cde8dbb
Binary files /dev/null and b/testdata/zoneinfo/Chile/Continental differ
diff --git a/testdata/zoneinfo/Chile/EasterIsland b/testdata/zoneinfo/Chile/EasterIsland
new file mode 100644
index 0000000..d29bcd6
Binary files /dev/null and b/testdata/zoneinfo/Chile/EasterIsland differ
diff --git a/testdata/zoneinfo/Cuba b/testdata/zoneinfo/Cuba
new file mode 100644
index 0000000..e06629d
Binary files /dev/null and b/testdata/zoneinfo/Cuba differ
diff --git a/testdata/zoneinfo/EET b/testdata/zoneinfo/EET
new file mode 100644
index 0000000..378919e
Binary files /dev/null and b/testdata/zoneinfo/EET differ
diff --git a/testdata/zoneinfo/EST b/testdata/zoneinfo/EST
new file mode 100644
index 0000000..3ae9691
Binary files /dev/null and b/testdata/zoneinfo/EST differ
diff --git a/testdata/zoneinfo/EST5EDT b/testdata/zoneinfo/EST5EDT
new file mode 100644
index 0000000..50c95e0
Binary files /dev/null and b/testdata/zoneinfo/EST5EDT differ
diff --git a/testdata/zoneinfo/Egypt b/testdata/zoneinfo/Egypt
new file mode 100644
index 0000000..ea38c97
Binary files /dev/null and b/testdata/zoneinfo/Egypt differ
diff --git a/testdata/zoneinfo/Eire b/testdata/zoneinfo/Eire
new file mode 100644
index 0000000..4a45ea8
Binary files /dev/null and b/testdata/zoneinfo/Eire differ
diff --git a/testdata/zoneinfo/Etc/GMT b/testdata/zoneinfo/Etc/GMT
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT differ
diff --git a/testdata/zoneinfo/Etc/GMT+0 b/testdata/zoneinfo/Etc/GMT+0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+0 differ
diff --git a/testdata/zoneinfo/Etc/GMT+1 b/testdata/zoneinfo/Etc/GMT+1
new file mode 100644
index 0000000..98d5dcf
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+1 differ
diff --git a/testdata/zoneinfo/Etc/GMT+10 b/testdata/zoneinfo/Etc/GMT+10
new file mode 100644
index 0000000..ecb287e
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+10 differ
diff --git a/testdata/zoneinfo/Etc/GMT+11 b/testdata/zoneinfo/Etc/GMT+11
new file mode 100644
index 0000000..e941412
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+11 differ
diff --git a/testdata/zoneinfo/Etc/GMT+12 b/testdata/zoneinfo/Etc/GMT+12
new file mode 100644
index 0000000..9c95bd0
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+12 differ
diff --git a/testdata/zoneinfo/Etc/GMT+2 b/testdata/zoneinfo/Etc/GMT+2
new file mode 100644
index 0000000..6d5ce3d
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+2 differ
diff --git a/testdata/zoneinfo/Etc/GMT+3 b/testdata/zoneinfo/Etc/GMT+3
new file mode 100644
index 0000000..5ef7be7
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+3 differ
diff --git a/testdata/zoneinfo/Etc/GMT+4 b/testdata/zoneinfo/Etc/GMT+4
new file mode 100644
index 0000000..75f1621
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+4 differ
diff --git a/testdata/zoneinfo/Etc/GMT+5 b/testdata/zoneinfo/Etc/GMT+5
new file mode 100644
index 0000000..589990a
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+5 differ
diff --git a/testdata/zoneinfo/Etc/GMT+6 b/testdata/zoneinfo/Etc/GMT+6
new file mode 100644
index 0000000..fcb60ca
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+6 differ
diff --git a/testdata/zoneinfo/Etc/GMT+7 b/testdata/zoneinfo/Etc/GMT+7
new file mode 100644
index 0000000..c0427a4
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+7 differ
diff --git a/testdata/zoneinfo/Etc/GMT+8 b/testdata/zoneinfo/Etc/GMT+8
new file mode 100644
index 0000000..9bdc228
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+8 differ
diff --git a/testdata/zoneinfo/Etc/GMT+9 b/testdata/zoneinfo/Etc/GMT+9
new file mode 100644
index 0000000..ca7a81f
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT+9 differ
diff --git a/testdata/zoneinfo/Etc/GMT-0 b/testdata/zoneinfo/Etc/GMT-0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-0 differ
diff --git a/testdata/zoneinfo/Etc/GMT-1 b/testdata/zoneinfo/Etc/GMT-1
new file mode 100644
index 0000000..cb45601
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-1 differ
diff --git a/testdata/zoneinfo/Etc/GMT-10 b/testdata/zoneinfo/Etc/GMT-10
new file mode 100644
index 0000000..11d988e
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-10 differ
diff --git a/testdata/zoneinfo/Etc/GMT-11 b/testdata/zoneinfo/Etc/GMT-11
new file mode 100644
index 0000000..f4c5d5c
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-11 differ
diff --git a/testdata/zoneinfo/Etc/GMT-12 b/testdata/zoneinfo/Etc/GMT-12
new file mode 100644
index 0000000..cd397b0
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-12 differ
diff --git a/testdata/zoneinfo/Etc/GMT-13 b/testdata/zoneinfo/Etc/GMT-13
new file mode 100644
index 0000000..8fad7c6
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-13 differ
diff --git a/testdata/zoneinfo/Etc/GMT-14 b/testdata/zoneinfo/Etc/GMT-14
new file mode 100644
index 0000000..a595e60
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-14 differ
diff --git a/testdata/zoneinfo/Etc/GMT-2 b/testdata/zoneinfo/Etc/GMT-2
new file mode 100644
index 0000000..97b44a9
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-2 differ
diff --git a/testdata/zoneinfo/Etc/GMT-3 b/testdata/zoneinfo/Etc/GMT-3
new file mode 100644
index 0000000..4eb17ff
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-3 differ
diff --git a/testdata/zoneinfo/Etc/GMT-4 b/testdata/zoneinfo/Etc/GMT-4
new file mode 100644
index 0000000..13aef80
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-4 differ
diff --git a/testdata/zoneinfo/Etc/GMT-5 b/testdata/zoneinfo/Etc/GMT-5
new file mode 100644
index 0000000..83a2816
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-5 differ
diff --git a/testdata/zoneinfo/Etc/GMT-6 b/testdata/zoneinfo/Etc/GMT-6
new file mode 100644
index 0000000..79a983e
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-6 differ
diff --git a/testdata/zoneinfo/Etc/GMT-7 b/testdata/zoneinfo/Etc/GMT-7
new file mode 100644
index 0000000..e136690
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-7 differ
diff --git a/testdata/zoneinfo/Etc/GMT-8 b/testdata/zoneinfo/Etc/GMT-8
new file mode 100644
index 0000000..bc70fe4
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-8 differ
diff --git a/testdata/zoneinfo/Etc/GMT-9 b/testdata/zoneinfo/Etc/GMT-9
new file mode 100644
index 0000000..d18cedd
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT-9 differ
diff --git a/testdata/zoneinfo/Etc/GMT0 b/testdata/zoneinfo/Etc/GMT0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Etc/GMT0 differ
diff --git a/testdata/zoneinfo/Etc/Greenwich b/testdata/zoneinfo/Etc/Greenwich
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Etc/Greenwich differ
diff --git a/testdata/zoneinfo/Etc/UCT b/testdata/zoneinfo/Etc/UCT
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Etc/UCT differ
diff --git a/testdata/zoneinfo/Etc/UTC b/testdata/zoneinfo/Etc/UTC
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Etc/UTC differ
diff --git a/testdata/zoneinfo/Etc/Universal b/testdata/zoneinfo/Etc/Universal
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Etc/Universal differ
diff --git a/testdata/zoneinfo/Etc/Zulu b/testdata/zoneinfo/Etc/Zulu
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Etc/Zulu differ
diff --git a/testdata/zoneinfo/Europe/Amsterdam b/testdata/zoneinfo/Europe/Amsterdam
new file mode 100644
index 0000000..4a6fa1d
Binary files /dev/null and b/testdata/zoneinfo/Europe/Amsterdam differ
diff --git a/testdata/zoneinfo/Europe/Andorra b/testdata/zoneinfo/Europe/Andorra
new file mode 100644
index 0000000..38685d4
Binary files /dev/null and b/testdata/zoneinfo/Europe/Andorra differ
diff --git a/testdata/zoneinfo/Europe/Astrakhan b/testdata/zoneinfo/Europe/Astrakhan
new file mode 100644
index 0000000..aff8d82
Binary files /dev/null and b/testdata/zoneinfo/Europe/Astrakhan differ
diff --git a/testdata/zoneinfo/Europe/Athens b/testdata/zoneinfo/Europe/Athens
new file mode 100644
index 0000000..231bf9c
Binary files /dev/null and b/testdata/zoneinfo/Europe/Athens differ
diff --git a/testdata/zoneinfo/Europe/Belfast b/testdata/zoneinfo/Europe/Belfast
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/Europe/Belfast differ
diff --git a/testdata/zoneinfo/Europe/Belgrade b/testdata/zoneinfo/Europe/Belgrade
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Belgrade differ
diff --git a/testdata/zoneinfo/Europe/Berlin b/testdata/zoneinfo/Europe/Berlin
new file mode 100644
index 0000000..465546b
Binary files /dev/null and b/testdata/zoneinfo/Europe/Berlin differ
diff --git a/testdata/zoneinfo/Europe/Bratislava b/testdata/zoneinfo/Europe/Bratislava
new file mode 100644
index 0000000..fb7c145
Binary files /dev/null and b/testdata/zoneinfo/Europe/Bratislava differ
diff --git a/testdata/zoneinfo/Europe/Brussels b/testdata/zoneinfo/Europe/Brussels
new file mode 100644
index 0000000..3197327
Binary files /dev/null and b/testdata/zoneinfo/Europe/Brussels differ
diff --git a/testdata/zoneinfo/Europe/Bucharest b/testdata/zoneinfo/Europe/Bucharest
new file mode 100644
index 0000000..efa689b
Binary files /dev/null and b/testdata/zoneinfo/Europe/Bucharest differ
diff --git a/testdata/zoneinfo/Europe/Budapest b/testdata/zoneinfo/Europe/Budapest
new file mode 100644
index 0000000..940be46
Binary files /dev/null and b/testdata/zoneinfo/Europe/Budapest differ
diff --git a/testdata/zoneinfo/Europe/Busingen b/testdata/zoneinfo/Europe/Busingen
new file mode 100644
index 0000000..388df29
Binary files /dev/null and b/testdata/zoneinfo/Europe/Busingen differ
diff --git a/testdata/zoneinfo/Europe/Chisinau b/testdata/zoneinfo/Europe/Chisinau
new file mode 100644
index 0000000..6970b14
Binary files /dev/null and b/testdata/zoneinfo/Europe/Chisinau differ
diff --git a/testdata/zoneinfo/Europe/Copenhagen b/testdata/zoneinfo/Europe/Copenhagen
new file mode 100644
index 0000000..45984a7
Binary files /dev/null and b/testdata/zoneinfo/Europe/Copenhagen differ
diff --git a/testdata/zoneinfo/Europe/Dublin b/testdata/zoneinfo/Europe/Dublin
new file mode 100644
index 0000000..4a45ea8
Binary files /dev/null and b/testdata/zoneinfo/Europe/Dublin differ
diff --git a/testdata/zoneinfo/Europe/Gibraltar b/testdata/zoneinfo/Europe/Gibraltar
new file mode 100644
index 0000000..017bb2e
Binary files /dev/null and b/testdata/zoneinfo/Europe/Gibraltar differ
diff --git a/testdata/zoneinfo/Europe/Guernsey b/testdata/zoneinfo/Europe/Guernsey
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/Europe/Guernsey differ
diff --git a/testdata/zoneinfo/Europe/Helsinki b/testdata/zoneinfo/Europe/Helsinki
new file mode 100644
index 0000000..ff5e565
Binary files /dev/null and b/testdata/zoneinfo/Europe/Helsinki differ
diff --git a/testdata/zoneinfo/Europe/Isle_of_Man b/testdata/zoneinfo/Europe/Isle_of_Man
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/Europe/Isle_of_Man differ
diff --git a/testdata/zoneinfo/Europe/Istanbul b/testdata/zoneinfo/Europe/Istanbul
new file mode 100644
index 0000000..c891866
Binary files /dev/null and b/testdata/zoneinfo/Europe/Istanbul differ
diff --git a/testdata/zoneinfo/Europe/Jersey b/testdata/zoneinfo/Europe/Jersey
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/Europe/Jersey differ
diff --git a/testdata/zoneinfo/Europe/Kaliningrad b/testdata/zoneinfo/Europe/Kaliningrad
new file mode 100644
index 0000000..0ec4756
Binary files /dev/null and b/testdata/zoneinfo/Europe/Kaliningrad differ
diff --git a/testdata/zoneinfo/Europe/Kiev b/testdata/zoneinfo/Europe/Kiev
new file mode 100644
index 0000000..4e02685
Binary files /dev/null and b/testdata/zoneinfo/Europe/Kiev differ
diff --git a/testdata/zoneinfo/Europe/Kirov b/testdata/zoneinfo/Europe/Kirov
new file mode 100644
index 0000000..d1c93c5
Binary files /dev/null and b/testdata/zoneinfo/Europe/Kirov differ
diff --git a/testdata/zoneinfo/Europe/Lisbon b/testdata/zoneinfo/Europe/Lisbon
new file mode 100644
index 0000000..f0c70b6
Binary files /dev/null and b/testdata/zoneinfo/Europe/Lisbon differ
diff --git a/testdata/zoneinfo/Europe/Ljubljana b/testdata/zoneinfo/Europe/Ljubljana
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Ljubljana differ
diff --git a/testdata/zoneinfo/Europe/London b/testdata/zoneinfo/Europe/London
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/Europe/London differ
diff --git a/testdata/zoneinfo/Europe/Luxembourg b/testdata/zoneinfo/Europe/Luxembourg
new file mode 100644
index 0000000..682bcbf
Binary files /dev/null and b/testdata/zoneinfo/Europe/Luxembourg differ
diff --git a/testdata/zoneinfo/Europe/Madrid b/testdata/zoneinfo/Europe/Madrid
new file mode 100644
index 0000000..60bdf4d
Binary files /dev/null and b/testdata/zoneinfo/Europe/Madrid differ
diff --git a/testdata/zoneinfo/Europe/Malta b/testdata/zoneinfo/Europe/Malta
new file mode 100644
index 0000000..27539c2
Binary files /dev/null and b/testdata/zoneinfo/Europe/Malta differ
diff --git a/testdata/zoneinfo/Europe/Mariehamn b/testdata/zoneinfo/Europe/Mariehamn
new file mode 100644
index 0000000..ff5e565
Binary files /dev/null and b/testdata/zoneinfo/Europe/Mariehamn differ
diff --git a/testdata/zoneinfo/Europe/Minsk b/testdata/zoneinfo/Europe/Minsk
new file mode 100644
index 0000000..30d3a67
Binary files /dev/null and b/testdata/zoneinfo/Europe/Minsk differ
diff --git a/testdata/zoneinfo/Europe/Monaco b/testdata/zoneinfo/Europe/Monaco
new file mode 100644
index 0000000..f30dfc7
Binary files /dev/null and b/testdata/zoneinfo/Europe/Monaco differ
diff --git a/testdata/zoneinfo/Europe/Moscow b/testdata/zoneinfo/Europe/Moscow
new file mode 100644
index 0000000..5e6b6de
Binary files /dev/null and b/testdata/zoneinfo/Europe/Moscow differ
diff --git a/testdata/zoneinfo/Europe/Nicosia b/testdata/zoneinfo/Europe/Nicosia
new file mode 100644
index 0000000..c210d0a
Binary files /dev/null and b/testdata/zoneinfo/Europe/Nicosia differ
diff --git a/testdata/zoneinfo/Europe/Oslo b/testdata/zoneinfo/Europe/Oslo
new file mode 100644
index 0000000..dfc5095
Binary files /dev/null and b/testdata/zoneinfo/Europe/Oslo differ
diff --git a/testdata/zoneinfo/Europe/Paris b/testdata/zoneinfo/Europe/Paris
new file mode 100644
index 0000000..00a2726
Binary files /dev/null and b/testdata/zoneinfo/Europe/Paris differ
diff --git a/testdata/zoneinfo/Europe/Podgorica b/testdata/zoneinfo/Europe/Podgorica
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Podgorica differ
diff --git a/testdata/zoneinfo/Europe/Prague b/testdata/zoneinfo/Europe/Prague
new file mode 100644
index 0000000..fb7c145
Binary files /dev/null and b/testdata/zoneinfo/Europe/Prague differ
diff --git a/testdata/zoneinfo/Europe/Riga b/testdata/zoneinfo/Europe/Riga
new file mode 100644
index 0000000..26af4c9
Binary files /dev/null and b/testdata/zoneinfo/Europe/Riga differ
diff --git a/testdata/zoneinfo/Europe/Rome b/testdata/zoneinfo/Europe/Rome
new file mode 100644
index 0000000..639ca3b
Binary files /dev/null and b/testdata/zoneinfo/Europe/Rome differ
diff --git a/testdata/zoneinfo/Europe/Samara b/testdata/zoneinfo/Europe/Samara
new file mode 100644
index 0000000..8d0c26e
Binary files /dev/null and b/testdata/zoneinfo/Europe/Samara differ
diff --git a/testdata/zoneinfo/Europe/San_Marino b/testdata/zoneinfo/Europe/San_Marino
new file mode 100644
index 0000000..639ca3b
Binary files /dev/null and b/testdata/zoneinfo/Europe/San_Marino differ
diff --git a/testdata/zoneinfo/Europe/Sarajevo b/testdata/zoneinfo/Europe/Sarajevo
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Sarajevo differ
diff --git a/testdata/zoneinfo/Europe/Saratov b/testdata/zoneinfo/Europe/Saratov
new file mode 100644
index 0000000..2684d8f
Binary files /dev/null and b/testdata/zoneinfo/Europe/Saratov differ
diff --git a/testdata/zoneinfo/Europe/Simferopol b/testdata/zoneinfo/Europe/Simferopol
new file mode 100644
index 0000000..40d23c0
Binary files /dev/null and b/testdata/zoneinfo/Europe/Simferopol differ
diff --git a/testdata/zoneinfo/Europe/Skopje b/testdata/zoneinfo/Europe/Skopje
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Skopje differ
diff --git a/testdata/zoneinfo/Europe/Sofia b/testdata/zoneinfo/Europe/Sofia
new file mode 100644
index 0000000..eabc972
Binary files /dev/null and b/testdata/zoneinfo/Europe/Sofia differ
diff --git a/testdata/zoneinfo/Europe/Stockholm b/testdata/zoneinfo/Europe/Stockholm
new file mode 100644
index 0000000..dd3eb32
Binary files /dev/null and b/testdata/zoneinfo/Europe/Stockholm differ
diff --git a/testdata/zoneinfo/Europe/Tallinn b/testdata/zoneinfo/Europe/Tallinn
new file mode 100644
index 0000000..5321bbd
Binary files /dev/null and b/testdata/zoneinfo/Europe/Tallinn differ
diff --git a/testdata/zoneinfo/Europe/Tirane b/testdata/zoneinfo/Europe/Tirane
new file mode 100644
index 0000000..743a733
Binary files /dev/null and b/testdata/zoneinfo/Europe/Tirane differ
diff --git a/testdata/zoneinfo/Europe/Tiraspol b/testdata/zoneinfo/Europe/Tiraspol
new file mode 100644
index 0000000..6970b14
Binary files /dev/null and b/testdata/zoneinfo/Europe/Tiraspol differ
diff --git a/testdata/zoneinfo/Europe/Ulyanovsk b/testdata/zoneinfo/Europe/Ulyanovsk
new file mode 100644
index 0000000..bb842cb
Binary files /dev/null and b/testdata/zoneinfo/Europe/Ulyanovsk differ
diff --git a/testdata/zoneinfo/Europe/Uzhgorod b/testdata/zoneinfo/Europe/Uzhgorod
new file mode 100644
index 0000000..d4c3591
Binary files /dev/null and b/testdata/zoneinfo/Europe/Uzhgorod differ
diff --git a/testdata/zoneinfo/Europe/Vaduz b/testdata/zoneinfo/Europe/Vaduz
new file mode 100644
index 0000000..388df29
Binary files /dev/null and b/testdata/zoneinfo/Europe/Vaduz differ
diff --git a/testdata/zoneinfo/Europe/Vatican b/testdata/zoneinfo/Europe/Vatican
new file mode 100644
index 0000000..639ca3b
Binary files /dev/null and b/testdata/zoneinfo/Europe/Vatican differ
diff --git a/testdata/zoneinfo/Europe/Vienna b/testdata/zoneinfo/Europe/Vienna
new file mode 100644
index 0000000..75339e9
Binary files /dev/null and b/testdata/zoneinfo/Europe/Vienna differ
diff --git a/testdata/zoneinfo/Europe/Vilnius b/testdata/zoneinfo/Europe/Vilnius
new file mode 100644
index 0000000..75b2eeb
Binary files /dev/null and b/testdata/zoneinfo/Europe/Vilnius differ
diff --git a/testdata/zoneinfo/Europe/Volgograd b/testdata/zoneinfo/Europe/Volgograd
new file mode 100644
index 0000000..c517002
Binary files /dev/null and b/testdata/zoneinfo/Europe/Volgograd differ
diff --git a/testdata/zoneinfo/Europe/Warsaw b/testdata/zoneinfo/Europe/Warsaw
new file mode 100644
index 0000000..efe1a40
Binary files /dev/null and b/testdata/zoneinfo/Europe/Warsaw differ
diff --git a/testdata/zoneinfo/Europe/Zagreb b/testdata/zoneinfo/Europe/Zagreb
new file mode 100644
index 0000000..a1bf928
Binary files /dev/null and b/testdata/zoneinfo/Europe/Zagreb differ
diff --git a/testdata/zoneinfo/Europe/Zaporozhye b/testdata/zoneinfo/Europe/Zaporozhye
new file mode 100644
index 0000000..71819a5
Binary files /dev/null and b/testdata/zoneinfo/Europe/Zaporozhye differ
diff --git a/testdata/zoneinfo/Europe/Zurich b/testdata/zoneinfo/Europe/Zurich
new file mode 100644
index 0000000..388df29
Binary files /dev/null and b/testdata/zoneinfo/Europe/Zurich differ
diff --git a/testdata/zoneinfo/Factory b/testdata/zoneinfo/Factory
new file mode 100644
index 0000000..b4dd773
Binary files /dev/null and b/testdata/zoneinfo/Factory differ
diff --git a/testdata/zoneinfo/GB b/testdata/zoneinfo/GB
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/GB differ
diff --git a/testdata/zoneinfo/GB-Eire b/testdata/zoneinfo/GB-Eire
new file mode 100644
index 0000000..323cd38
Binary files /dev/null and b/testdata/zoneinfo/GB-Eire differ
diff --git a/testdata/zoneinfo/GMT b/testdata/zoneinfo/GMT
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/GMT differ
diff --git a/testdata/zoneinfo/GMT+0 b/testdata/zoneinfo/GMT+0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/GMT+0 differ
diff --git a/testdata/zoneinfo/GMT-0 b/testdata/zoneinfo/GMT-0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/GMT-0 differ
diff --git a/testdata/zoneinfo/GMT0 b/testdata/zoneinfo/GMT0
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/GMT0 differ
diff --git a/testdata/zoneinfo/Greenwich b/testdata/zoneinfo/Greenwich
new file mode 100644
index 0000000..157573b
Binary files /dev/null and b/testdata/zoneinfo/Greenwich differ
diff --git a/testdata/zoneinfo/HST b/testdata/zoneinfo/HST
new file mode 100644
index 0000000..160a53e
Binary files /dev/null and b/testdata/zoneinfo/HST differ
diff --git a/testdata/zoneinfo/Hongkong b/testdata/zoneinfo/Hongkong
new file mode 100644
index 0000000..c80e364
Binary files /dev/null and b/testdata/zoneinfo/Hongkong differ
diff --git a/testdata/zoneinfo/Iceland b/testdata/zoneinfo/Iceland
new file mode 100644
index 0000000..2451aca
Binary files /dev/null and b/testdata/zoneinfo/Iceland differ
diff --git a/testdata/zoneinfo/Indian/Antananarivo b/testdata/zoneinfo/Indian/Antananarivo
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Indian/Antananarivo differ
diff --git a/testdata/zoneinfo/Indian/Chagos b/testdata/zoneinfo/Indian/Chagos
new file mode 100644
index 0000000..8b8ce22
Binary files /dev/null and b/testdata/zoneinfo/Indian/Chagos differ
diff --git a/testdata/zoneinfo/Indian/Christmas b/testdata/zoneinfo/Indian/Christmas
new file mode 100644
index 0000000..766024b
Binary files /dev/null and b/testdata/zoneinfo/Indian/Christmas differ
diff --git a/testdata/zoneinfo/Indian/Cocos b/testdata/zoneinfo/Indian/Cocos
new file mode 100644
index 0000000..1175034
Binary files /dev/null and b/testdata/zoneinfo/Indian/Cocos differ
diff --git a/testdata/zoneinfo/Indian/Comoro b/testdata/zoneinfo/Indian/Comoro
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Indian/Comoro differ
diff --git a/testdata/zoneinfo/Indian/Kerguelen b/testdata/zoneinfo/Indian/Kerguelen
new file mode 100644
index 0000000..8ce93e0
Binary files /dev/null and b/testdata/zoneinfo/Indian/Kerguelen differ
diff --git a/testdata/zoneinfo/Indian/Mahe b/testdata/zoneinfo/Indian/Mahe
new file mode 100644
index 0000000..e7fccf8
Binary files /dev/null and b/testdata/zoneinfo/Indian/Mahe differ
diff --git a/testdata/zoneinfo/Indian/Maldives b/testdata/zoneinfo/Indian/Maldives
new file mode 100644
index 0000000..58a82e4
Binary files /dev/null and b/testdata/zoneinfo/Indian/Maldives differ
diff --git a/testdata/zoneinfo/Indian/Mauritius b/testdata/zoneinfo/Indian/Mauritius
new file mode 100644
index 0000000..7c11134
Binary files /dev/null and b/testdata/zoneinfo/Indian/Mauritius differ
diff --git a/testdata/zoneinfo/Indian/Mayotte b/testdata/zoneinfo/Indian/Mayotte
new file mode 100644
index 0000000..5f4ebcb
Binary files /dev/null and b/testdata/zoneinfo/Indian/Mayotte differ
diff --git a/testdata/zoneinfo/Indian/Reunion b/testdata/zoneinfo/Indian/Reunion
new file mode 100644
index 0000000..248a7c9
Binary files /dev/null and b/testdata/zoneinfo/Indian/Reunion differ
diff --git a/testdata/zoneinfo/Iran b/testdata/zoneinfo/Iran
new file mode 100644
index 0000000..f1555f0
Binary files /dev/null and b/testdata/zoneinfo/Iran differ
diff --git a/testdata/zoneinfo/Israel b/testdata/zoneinfo/Israel
new file mode 100644
index 0000000..4c49bbf
Binary files /dev/null and b/testdata/zoneinfo/Israel differ
diff --git a/testdata/zoneinfo/Jamaica b/testdata/zoneinfo/Jamaica
new file mode 100644
index 0000000..be6b1b6
Binary files /dev/null and b/testdata/zoneinfo/Jamaica differ
diff --git a/testdata/zoneinfo/Japan b/testdata/zoneinfo/Japan
new file mode 100644
index 0000000..1aa066c
Binary files /dev/null and b/testdata/zoneinfo/Japan differ
diff --git a/testdata/zoneinfo/Kwajalein b/testdata/zoneinfo/Kwajalein
new file mode 100644
index 0000000..9416d52
Binary files /dev/null and b/testdata/zoneinfo/Kwajalein differ
diff --git a/testdata/zoneinfo/Libya b/testdata/zoneinfo/Libya
new file mode 100644
index 0000000..e0c8997
Binary files /dev/null and b/testdata/zoneinfo/Libya differ
diff --git a/testdata/zoneinfo/MET b/testdata/zoneinfo/MET
new file mode 100644
index 0000000..6f0558c
Binary files /dev/null and b/testdata/zoneinfo/MET differ
diff --git a/testdata/zoneinfo/MST b/testdata/zoneinfo/MST
new file mode 100644
index 0000000..a0953d1
Binary files /dev/null and b/testdata/zoneinfo/MST differ
diff --git a/testdata/zoneinfo/MST7MDT b/testdata/zoneinfo/MST7MDT
new file mode 100644
index 0000000..137867c
Binary files /dev/null and b/testdata/zoneinfo/MST7MDT differ
diff --git a/testdata/zoneinfo/Mexico/BajaNorte b/testdata/zoneinfo/Mexico/BajaNorte
new file mode 100644
index 0000000..19ccd35
Binary files /dev/null and b/testdata/zoneinfo/Mexico/BajaNorte differ
diff --git a/testdata/zoneinfo/Mexico/BajaSur b/testdata/zoneinfo/Mexico/BajaSur
new file mode 100644
index 0000000..4c819fa
Binary files /dev/null and b/testdata/zoneinfo/Mexico/BajaSur differ
diff --git a/testdata/zoneinfo/Mexico/General b/testdata/zoneinfo/Mexico/General
new file mode 100644
index 0000000..ffcf8be
Binary files /dev/null and b/testdata/zoneinfo/Mexico/General differ
diff --git a/testdata/zoneinfo/NZ b/testdata/zoneinfo/NZ
new file mode 100644
index 0000000..afb3929
Binary files /dev/null and b/testdata/zoneinfo/NZ differ
diff --git a/testdata/zoneinfo/NZ-CHAT b/testdata/zoneinfo/NZ-CHAT
new file mode 100644
index 0000000..f06065e
Binary files /dev/null and b/testdata/zoneinfo/NZ-CHAT differ
diff --git a/testdata/zoneinfo/Navajo b/testdata/zoneinfo/Navajo
new file mode 100644
index 0000000..09e54e5
Binary files /dev/null and b/testdata/zoneinfo/Navajo differ
diff --git a/testdata/zoneinfo/PRC b/testdata/zoneinfo/PRC
new file mode 100644
index 0000000..d6b6698
Binary files /dev/null and b/testdata/zoneinfo/PRC differ
diff --git a/testdata/zoneinfo/PST8PDT b/testdata/zoneinfo/PST8PDT
new file mode 100644
index 0000000..fde4833
Binary files /dev/null and b/testdata/zoneinfo/PST8PDT differ
diff --git a/testdata/zoneinfo/Pacific/Apia b/testdata/zoneinfo/Pacific/Apia
new file mode 100644
index 0000000..a6b835a
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Apia differ
diff --git a/testdata/zoneinfo/Pacific/Auckland b/testdata/zoneinfo/Pacific/Auckland
new file mode 100644
index 0000000..afb3929
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Auckland differ
diff --git a/testdata/zoneinfo/Pacific/Bougainville b/testdata/zoneinfo/Pacific/Bougainville
new file mode 100644
index 0000000..7c66709
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Bougainville differ
diff --git a/testdata/zoneinfo/Pacific/Chatham b/testdata/zoneinfo/Pacific/Chatham
new file mode 100644
index 0000000..f06065e
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Chatham differ
diff --git a/testdata/zoneinfo/Pacific/Chuuk b/testdata/zoneinfo/Pacific/Chuuk
new file mode 100644
index 0000000..ea3fb5c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Chuuk differ
diff --git a/testdata/zoneinfo/Pacific/Easter b/testdata/zoneinfo/Pacific/Easter
new file mode 100644
index 0000000..d29bcd6
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Easter differ
diff --git a/testdata/zoneinfo/Pacific/Efate b/testdata/zoneinfo/Pacific/Efate
new file mode 100644
index 0000000..bf7471d
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Efate differ
diff --git a/testdata/zoneinfo/Pacific/Enderbury b/testdata/zoneinfo/Pacific/Enderbury
new file mode 100644
index 0000000..2b6a060
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Enderbury differ
diff --git a/testdata/zoneinfo/Pacific/Fakaofo b/testdata/zoneinfo/Pacific/Fakaofo
new file mode 100644
index 0000000..b7b3021
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Fakaofo differ
diff --git a/testdata/zoneinfo/Pacific/Fiji b/testdata/zoneinfo/Pacific/Fiji
new file mode 100644
index 0000000..8b2dd52
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Fiji differ
diff --git a/testdata/zoneinfo/Pacific/Funafuti b/testdata/zoneinfo/Pacific/Funafuti
new file mode 100644
index 0000000..78ab35b
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Funafuti differ
diff --git a/testdata/zoneinfo/Pacific/Galapagos b/testdata/zoneinfo/Pacific/Galapagos
new file mode 100644
index 0000000..a9403ec
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Galapagos differ
diff --git a/testdata/zoneinfo/Pacific/Gambier b/testdata/zoneinfo/Pacific/Gambier
new file mode 100644
index 0000000..ddfc34f
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Gambier differ
diff --git a/testdata/zoneinfo/Pacific/Guadalcanal b/testdata/zoneinfo/Pacific/Guadalcanal
new file mode 100644
index 0000000..720c679
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Guadalcanal differ
diff --git a/testdata/zoneinfo/Pacific/Guam b/testdata/zoneinfo/Pacific/Guam
new file mode 100644
index 0000000..bf9a2d9
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Guam differ
diff --git a/testdata/zoneinfo/Pacific/Honolulu b/testdata/zoneinfo/Pacific/Honolulu
new file mode 100644
index 0000000..40e3d49
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Honolulu differ
diff --git a/testdata/zoneinfo/Pacific/Johnston b/testdata/zoneinfo/Pacific/Johnston
new file mode 100644
index 0000000..40e3d49
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Johnston differ
diff --git a/testdata/zoneinfo/Pacific/Kanton b/testdata/zoneinfo/Pacific/Kanton
new file mode 100644
index 0000000..2b6a060
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Kanton differ
diff --git a/testdata/zoneinfo/Pacific/Kiritimati b/testdata/zoneinfo/Pacific/Kiritimati
new file mode 100644
index 0000000..2f676d3
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Kiritimati differ
diff --git a/testdata/zoneinfo/Pacific/Kosrae b/testdata/zoneinfo/Pacific/Kosrae
new file mode 100644
index 0000000..f5d5824
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Kosrae differ
diff --git a/testdata/zoneinfo/Pacific/Kwajalein b/testdata/zoneinfo/Pacific/Kwajalein
new file mode 100644
index 0000000..9416d52
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Kwajalein differ
diff --git a/testdata/zoneinfo/Pacific/Majuro b/testdata/zoneinfo/Pacific/Majuro
new file mode 100644
index 0000000..9228ee0
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Majuro differ
diff --git a/testdata/zoneinfo/Pacific/Marquesas b/testdata/zoneinfo/Pacific/Marquesas
new file mode 100644
index 0000000..6ea24b7
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Marquesas differ
diff --git a/testdata/zoneinfo/Pacific/Midway b/testdata/zoneinfo/Pacific/Midway
new file mode 100644
index 0000000..001289c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Midway differ
diff --git a/testdata/zoneinfo/Pacific/Nauru b/testdata/zoneinfo/Pacific/Nauru
new file mode 100644
index 0000000..ae13aac
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Nauru differ
diff --git a/testdata/zoneinfo/Pacific/Niue b/testdata/zoneinfo/Pacific/Niue
new file mode 100644
index 0000000..be874e2
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Niue differ
diff --git a/testdata/zoneinfo/Pacific/Norfolk b/testdata/zoneinfo/Pacific/Norfolk
new file mode 100644
index 0000000..79e2a94
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Norfolk differ
diff --git a/testdata/zoneinfo/Pacific/Noumea b/testdata/zoneinfo/Pacific/Noumea
new file mode 100644
index 0000000..824f814
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Noumea differ
diff --git a/testdata/zoneinfo/Pacific/Pago_Pago b/testdata/zoneinfo/Pacific/Pago_Pago
new file mode 100644
index 0000000..001289c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Pago_Pago differ
diff --git a/testdata/zoneinfo/Pacific/Palau b/testdata/zoneinfo/Pacific/Palau
new file mode 100644
index 0000000..bc8eb7a
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Palau differ
diff --git a/testdata/zoneinfo/Pacific/Pitcairn b/testdata/zoneinfo/Pacific/Pitcairn
new file mode 100644
index 0000000..8a4ba4d
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Pitcairn differ
diff --git a/testdata/zoneinfo/Pacific/Pohnpei b/testdata/zoneinfo/Pacific/Pohnpei
new file mode 100644
index 0000000..b92b254
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Pohnpei differ
diff --git a/testdata/zoneinfo/Pacific/Ponape b/testdata/zoneinfo/Pacific/Ponape
new file mode 100644
index 0000000..b92b254
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Ponape differ
diff --git a/testdata/zoneinfo/Pacific/Port_Moresby b/testdata/zoneinfo/Pacific/Port_Moresby
new file mode 100644
index 0000000..5d8fc3a
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Port_Moresby differ
diff --git a/testdata/zoneinfo/Pacific/Rarotonga b/testdata/zoneinfo/Pacific/Rarotonga
new file mode 100644
index 0000000..7220bda
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Rarotonga differ
diff --git a/testdata/zoneinfo/Pacific/Saipan b/testdata/zoneinfo/Pacific/Saipan
new file mode 100644
index 0000000..bf9a2d9
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Saipan differ
diff --git a/testdata/zoneinfo/Pacific/Samoa b/testdata/zoneinfo/Pacific/Samoa
new file mode 100644
index 0000000..001289c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Samoa differ
diff --git a/testdata/zoneinfo/Pacific/Tahiti b/testdata/zoneinfo/Pacific/Tahiti
new file mode 100644
index 0000000..50a064f
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Tahiti differ
diff --git a/testdata/zoneinfo/Pacific/Tarawa b/testdata/zoneinfo/Pacific/Tarawa
new file mode 100644
index 0000000..6bc2168
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Tarawa differ
diff --git a/testdata/zoneinfo/Pacific/Tongatapu b/testdata/zoneinfo/Pacific/Tongatapu
new file mode 100644
index 0000000..f28c840
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Tongatapu differ
diff --git a/testdata/zoneinfo/Pacific/Truk b/testdata/zoneinfo/Pacific/Truk
new file mode 100644
index 0000000..ea3fb5c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Truk differ
diff --git a/testdata/zoneinfo/Pacific/Wake b/testdata/zoneinfo/Pacific/Wake
new file mode 100644
index 0000000..71cca88
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Wake differ
diff --git a/testdata/zoneinfo/Pacific/Wallis b/testdata/zoneinfo/Pacific/Wallis
new file mode 100644
index 0000000..4bce893
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Wallis differ
diff --git a/testdata/zoneinfo/Pacific/Yap b/testdata/zoneinfo/Pacific/Yap
new file mode 100644
index 0000000..ea3fb5c
Binary files /dev/null and b/testdata/zoneinfo/Pacific/Yap differ
diff --git a/testdata/zoneinfo/Poland b/testdata/zoneinfo/Poland
new file mode 100644
index 0000000..efe1a40
Binary files /dev/null and b/testdata/zoneinfo/Poland differ
diff --git a/testdata/zoneinfo/Portugal b/testdata/zoneinfo/Portugal
new file mode 100644
index 0000000..f0c70b6
Binary files /dev/null and b/testdata/zoneinfo/Portugal differ
diff --git a/testdata/zoneinfo/ROC b/testdata/zoneinfo/ROC
new file mode 100644
index 0000000..35d89d0
Binary files /dev/null and b/testdata/zoneinfo/ROC differ
diff --git a/testdata/zoneinfo/ROK b/testdata/zoneinfo/ROK
new file mode 100644
index 0000000..1755147
Binary files /dev/null and b/testdata/zoneinfo/ROK differ
diff --git a/testdata/zoneinfo/Singapore b/testdata/zoneinfo/Singapore
new file mode 100644
index 0000000..350d77e
Binary files /dev/null and b/testdata/zoneinfo/Singapore differ
diff --git a/testdata/zoneinfo/Turkey b/testdata/zoneinfo/Turkey
new file mode 100644
index 0000000..c891866
Binary files /dev/null and b/testdata/zoneinfo/Turkey differ
diff --git a/testdata/zoneinfo/UCT b/testdata/zoneinfo/UCT
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/UCT differ
diff --git a/testdata/zoneinfo/US/Alaska b/testdata/zoneinfo/US/Alaska
new file mode 100644
index 0000000..cdf0572
Binary files /dev/null and b/testdata/zoneinfo/US/Alaska differ
diff --git a/testdata/zoneinfo/US/Aleutian b/testdata/zoneinfo/US/Aleutian
new file mode 100644
index 0000000..b1497bd
Binary files /dev/null and b/testdata/zoneinfo/US/Aleutian differ
diff --git a/testdata/zoneinfo/US/Arizona b/testdata/zoneinfo/US/Arizona
new file mode 100644
index 0000000..c2bd2f9
Binary files /dev/null and b/testdata/zoneinfo/US/Arizona differ
diff --git a/testdata/zoneinfo/US/Central b/testdata/zoneinfo/US/Central
new file mode 100644
index 0000000..b016880
Binary files /dev/null and b/testdata/zoneinfo/US/Central differ
diff --git a/testdata/zoneinfo/US/East-Indiana b/testdata/zoneinfo/US/East-Indiana
new file mode 100644
index 0000000..6b08d15
Binary files /dev/null and b/testdata/zoneinfo/US/East-Indiana differ
diff --git a/testdata/zoneinfo/US/Eastern b/testdata/zoneinfo/US/Eastern
new file mode 100644
index 0000000..2b6c2ee
Binary files /dev/null and b/testdata/zoneinfo/US/Eastern differ
diff --git a/testdata/zoneinfo/US/Hawaii b/testdata/zoneinfo/US/Hawaii
new file mode 100644
index 0000000..40e3d49
Binary files /dev/null and b/testdata/zoneinfo/US/Hawaii differ
diff --git a/testdata/zoneinfo/US/Indiana-Starke b/testdata/zoneinfo/US/Indiana-Starke
new file mode 100644
index 0000000..b187d5f
Binary files /dev/null and b/testdata/zoneinfo/US/Indiana-Starke differ
diff --git a/testdata/zoneinfo/US/Michigan b/testdata/zoneinfo/US/Michigan
new file mode 100644
index 0000000..6eb3ac4
Binary files /dev/null and b/testdata/zoneinfo/US/Michigan differ
diff --git a/testdata/zoneinfo/US/Mountain b/testdata/zoneinfo/US/Mountain
new file mode 100644
index 0000000..09e54e5
Binary files /dev/null and b/testdata/zoneinfo/US/Mountain differ
diff --git a/testdata/zoneinfo/US/Pacific b/testdata/zoneinfo/US/Pacific
new file mode 100644
index 0000000..aaf0778
Binary files /dev/null and b/testdata/zoneinfo/US/Pacific differ
diff --git a/testdata/zoneinfo/US/Samoa b/testdata/zoneinfo/US/Samoa
new file mode 100644
index 0000000..001289c
Binary files /dev/null and b/testdata/zoneinfo/US/Samoa differ
diff --git a/testdata/zoneinfo/UTC b/testdata/zoneinfo/UTC
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/UTC differ
diff --git a/testdata/zoneinfo/Universal b/testdata/zoneinfo/Universal
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Universal differ
diff --git a/testdata/zoneinfo/W-SU b/testdata/zoneinfo/W-SU
new file mode 100644
index 0000000..5e6b6de
Binary files /dev/null and b/testdata/zoneinfo/W-SU differ
diff --git a/testdata/zoneinfo/WET b/testdata/zoneinfo/WET
new file mode 100644
index 0000000..423c6c2
Binary files /dev/null and b/testdata/zoneinfo/WET differ
diff --git a/testdata/zoneinfo/Zulu b/testdata/zoneinfo/Zulu
new file mode 100644
index 0000000..00841a6
Binary files /dev/null and b/testdata/zoneinfo/Zulu differ
diff --git a/testdata/zoneinfo/iso3166.tab b/testdata/zoneinfo/iso3166.tab
new file mode 100644
index 0000000..a4ff61a
--- /dev/null
+++ b/testdata/zoneinfo/iso3166.tab
@@ -0,0 +1,274 @@
+# ISO 3166 alpha-2 country codes
+#
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+#
+# From Paul Eggert (2015-05-02):
+# This file contains a table of two-letter country codes.  Columns are
+# separated by a single tab.  Lines beginning with '#' are comments.
+# All text uses UTF-8 encoding.  The columns of the table are as follows:
+#
+# 1.  ISO 3166-1 alpha-2 country code, current as of
+#     ISO 3166-1 N976 (2018-11-06).  See: Updates on ISO 3166-1
+#     https://isotc.iso.org/livelink/livelink/Open/16944257
+# 2.  The usual English name for the coded region,
+#     chosen so that alphabetic sorting of subsets produces helpful lists.
+#     This is not the same as the English name in the ISO 3166 tables.
+#
+# The table is sorted by country code.
+#
+# This table is intended as an aid for users, to help them select time
+# zone data appropriate for their practical needs.  It is not intended
+# to take or endorse any position on legal or territorial claims.
+#
+#country-
+#code	name of country, territory, area, or subdivision
+AD	Andorra
+AE	United Arab Emirates
+AF	Afghanistan
+AG	Antigua & Barbuda
+AI	Anguilla
+AL	Albania
+AM	Armenia
+AO	Angola
+AQ	Antarctica
+AR	Argentina
+AS	Samoa (American)
+AT	Austria
+AU	Australia
+AW	Aruba
+AX	Åland Islands
+AZ	Azerbaijan
+BA	Bosnia & Herzegovina
+BB	Barbados
+BD	Bangladesh
+BE	Belgium
+BF	Burkina Faso
+BG	Bulgaria
+BH	Bahrain
+BI	Burundi
+BJ	Benin
+BL	St Barthelemy
+BM	Bermuda
+BN	Brunei
+BO	Bolivia
+BQ	Caribbean NL
+BR	Brazil
+BS	Bahamas
+BT	Bhutan
+BV	Bouvet Island
+BW	Botswana
+BY	Belarus
+BZ	Belize
+CA	Canada
+CC	Cocos (Keeling) Islands
+CD	Congo (Dem. Rep.)
+CF	Central African Rep.
+CG	Congo (Rep.)
+CH	Switzerland
+CI	Côte d'Ivoire
+CK	Cook Islands
+CL	Chile
+CM	Cameroon
+CN	China
+CO	Colombia
+CR	Costa Rica
+CU	Cuba
+CV	Cape Verde
+CW	Curaçao
+CX	Christmas Island
+CY	Cyprus
+CZ	Czech Republic
+DE	Germany
+DJ	Djibouti
+DK	Denmark
+DM	Dominica
+DO	Dominican Republic
+DZ	Algeria
+EC	Ecuador
+EE	Estonia
+EG	Egypt
+EH	Western Sahara
+ER	Eritrea
+ES	Spain
+ET	Ethiopia
+FI	Finland
+FJ	Fiji
+FK	Falkland Islands
+FM	Micronesia
+FO	Faroe Islands
+FR	France
+GA	Gabon
+GB	Britain (UK)
+GD	Grenada
+GE	Georgia
+GF	French Guiana
+GG	Guernsey
+GH	Ghana
+GI	Gibraltar
+GL	Greenland
+GM	Gambia
+GN	Guinea
+GP	Guadeloupe
+GQ	Equatorial Guinea
+GR	Greece
+GS	South Georgia & the South Sandwich Islands
+GT	Guatemala
+GU	Guam
+GW	Guinea-Bissau
+GY	Guyana
+HK	Hong Kong
+HM	Heard Island & McDonald Islands
+HN	Honduras
+HR	Croatia
+HT	Haiti
+HU	Hungary
+ID	Indonesia
+IE	Ireland
+IL	Israel
+IM	Isle of Man
+IN	India
+IO	British Indian Ocean Territory
+IQ	Iraq
+IR	Iran
+IS	Iceland
+IT	Italy
+JE	Jersey
+JM	Jamaica
+JO	Jordan
+JP	Japan
+KE	Kenya
+KG	Kyrgyzstan
+KH	Cambodia
+KI	Kiribati
+KM	Comoros
+KN	St Kitts & Nevis
+KP	Korea (North)
+KR	Korea (South)
+KW	Kuwait
+KY	Cayman Islands
+KZ	Kazakhstan
+LA	Laos
+LB	Lebanon
+LC	St Lucia
+LI	Liechtenstein
+LK	Sri Lanka
+LR	Liberia
+LS	Lesotho
+LT	Lithuania
+LU	Luxembourg
+LV	Latvia
+LY	Libya
+MA	Morocco
+MC	Monaco
+MD	Moldova
+ME	Montenegro
+MF	St Martin (French)
+MG	Madagascar
+MH	Marshall Islands
+MK	North Macedonia
+ML	Mali
+MM	Myanmar (Burma)
+MN	Mongolia
+MO	Macau
+MP	Northern Mariana Islands
+MQ	Martinique
+MR	Mauritania
+MS	Montserrat
+MT	Malta
+MU	Mauritius
+MV	Maldives
+MW	Malawi
+MX	Mexico
+MY	Malaysia
+MZ	Mozambique
+NA	Namibia
+NC	New Caledonia
+NE	Niger
+NF	Norfolk Island
+NG	Nigeria
+NI	Nicaragua
+NL	Netherlands
+NO	Norway
+NP	Nepal
+NR	Nauru
+NU	Niue
+NZ	New Zealand
+OM	Oman
+PA	Panama
+PE	Peru
+PF	French Polynesia
+PG	Papua New Guinea
+PH	Philippines
+PK	Pakistan
+PL	Poland
+PM	St Pierre & Miquelon
+PN	Pitcairn
+PR	Puerto Rico
+PS	Palestine
+PT	Portugal
+PW	Palau
+PY	Paraguay
+QA	Qatar
+RE	Réunion
+RO	Romania
+RS	Serbia
+RU	Russia
+RW	Rwanda
+SA	Saudi Arabia
+SB	Solomon Islands
+SC	Seychelles
+SD	Sudan
+SE	Sweden
+SG	Singapore
+SH	St Helena
+SI	Slovenia
+SJ	Svalbard & Jan Mayen
+SK	Slovakia
+SL	Sierra Leone
+SM	San Marino
+SN	Senegal
+SO	Somalia
+SR	Suriname
+SS	South Sudan
+ST	Sao Tome & Principe
+SV	El Salvador
+SX	St Maarten (Dutch)
+SY	Syria
+SZ	Eswatini (Swaziland)
+TC	Turks & Caicos Is
+TD	Chad
+TF	French Southern & Antarctic Lands
+TG	Togo
+TH	Thailand
+TJ	Tajikistan
+TK	Tokelau
+TL	East Timor
+TM	Turkmenistan
+TN	Tunisia
+TO	Tonga
+TR	Turkey
+TT	Trinidad & Tobago
+TV	Tuvalu
+TW	Taiwan
+TZ	Tanzania
+UA	Ukraine
+UG	Uganda
+UM	US minor outlying islands
+US	United States
+UY	Uruguay
+UZ	Uzbekistan
+VA	Vatican City
+VC	St Vincent
+VE	Venezuela
+VG	Virgin Islands (UK)
+VI	Virgin Islands (US)
+VN	Vietnam
+VU	Vanuatu
+WF	Wallis & Futuna
+WS	Samoa (western)
+YE	Yemen
+YT	Mayotte
+ZA	South Africa
+ZM	Zambia
+ZW	Zimbabwe
diff --git a/testdata/zoneinfo/localtime b/testdata/zoneinfo/localtime
new file mode 100644
index 0000000..afeeb88
Binary files /dev/null and b/testdata/zoneinfo/localtime differ
diff --git a/testdata/zoneinfo/zone1970.tab b/testdata/zoneinfo/zone1970.tab
new file mode 100644
index 0000000..c614be8
--- /dev/null
+++ b/testdata/zoneinfo/zone1970.tab
@@ -0,0 +1,374 @@
+# tzdb timezone descriptions
+#
+# This file is in the public domain.
+#
+# From Paul Eggert (2018-06-27):
+# This file contains a table where each row stands for a timezone where
+# civil timestamps have agreed since 1970.  Columns are separated by
+# a single tab.  Lines beginning with '#' are comments.  All text uses
+# UTF-8 encoding.  The columns of the table are as follows:
+#
+# 1.  The countries that overlap the timezone, as a comma-separated list
+#     of ISO 3166 2-character country codes.  See the file 'iso3166.tab'.
+# 2.  Latitude and longitude of the timezone's principal location
+#     in ISO 6709 sign-degrees-minutes-seconds format,
+#     either ±DDMM±DDDMM or ±DDMMSS±DDDMMSS,
+#     first latitude (+ is north), then longitude (+ is east).
+# 3.  Timezone name used in value of TZ environment variable.
+#     Please see the theory.html file for how these names are chosen.
+#     If multiple timezones overlap a country, each has a row in the
+#     table, with each column 1 containing the country code.
+# 4.  Comments; present if and only if a country has multiple timezones.
+#
+# If a timezone covers multiple countries, the most-populous city is used,
+# and that country is listed first in column 1; any other countries
+# are listed alphabetically by country code.  The table is sorted
+# first by country code, then (if possible) by an order within the
+# country that (1) makes some geographical sense, and (2) puts the
+# most populous timezones first, where that does not contradict (1).
+#
+# This table is intended as an aid for users, to help them select timezones
+# appropriate for their practical needs.  It is not intended to take or
+# endorse any position on legal or territorial claims.
+#
+#country-
+#codes	coordinates	TZ	comments
+AD	+4230+00131	Europe/Andorra
+AE,OM	+2518+05518	Asia/Dubai
+AF	+3431+06912	Asia/Kabul
+AL	+4120+01950	Europe/Tirane
+AM	+4011+04430	Asia/Yerevan
+AQ	-6617+11031	Antarctica/Casey	Casey
+AQ	-6835+07758	Antarctica/Davis	Davis
+AQ	-6736+06253	Antarctica/Mawson	Mawson
+AQ	-6448-06406	Antarctica/Palmer	Palmer
+AQ	-6734-06808	Antarctica/Rothera	Rothera
+AQ	-720041+0023206	Antarctica/Troll	Troll
+AQ	-7824+10654	Antarctica/Vostok	Vostok
+AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
+AR	-3124-06411	America/Argentina/Cordoba	Argentina (most areas: CB, CC, CN, ER, FM, MN, SE, SF)
+AR	-2447-06525	America/Argentina/Salta	Salta (SA, LP, NQ, RN)
+AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
+AR	-2649-06513	America/Argentina/Tucuman	Tucumán (TM)
+AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT); Chubut (CH)
+AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
+AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
+AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
+AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
+AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
+AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
+AS,UM	-1416-17042	Pacific/Pago_Pago	Samoa, Midway
+AT	+4813+01620	Europe/Vienna
+AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
+AU	-5430+15857	Antarctica/Macquarie	Macquarie Island
+AU	-4253+14719	Australia/Hobart	Tasmania
+AU	-3749+14458	Australia/Melbourne	Victoria
+AU	-3352+15113	Australia/Sydney	New South Wales (most areas)
+AU	-3157+14127	Australia/Broken_Hill	New South Wales (Yancowinna)
+AU	-2728+15302	Australia/Brisbane	Queensland (most areas)
+AU	-2016+14900	Australia/Lindeman	Queensland (Whitsunday Islands)
+AU	-3455+13835	Australia/Adelaide	South Australia
+AU	-1228+13050	Australia/Darwin	Northern Territory
+AU	-3157+11551	Australia/Perth	Western Australia (most areas)
+AU	-3143+12852	Australia/Eucla	Western Australia (Eucla)
+AZ	+4023+04951	Asia/Baku
+BB	+1306-05937	America/Barbados
+BD	+2343+09025	Asia/Dhaka
+BE	+5050+00420	Europe/Brussels
+BG	+4241+02319	Europe/Sofia
+BM	+3217-06446	Atlantic/Bermuda
+BN	+0456+11455	Asia/Brunei
+BO	-1630-06809	America/La_Paz
+BR	-0351-03225	America/Noronha	Atlantic islands
+BR	-0127-04829	America/Belem	Pará (east); Amapá
+BR	-0343-03830	America/Fortaleza	Brazil (northeast: MA, PI, CE, RN, PB)
+BR	-0803-03454	America/Recife	Pernambuco
+BR	-0712-04812	America/Araguaina	Tocantins
+BR	-0940-03543	America/Maceio	Alagoas, Sergipe
+BR	-1259-03831	America/Bahia	Bahia
+BR	-2332-04637	America/Sao_Paulo	Brazil (southeast: GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
+BR	-1535-05605	America/Cuiaba	Mato Grosso
+BR	-0226-05452	America/Santarem	Pará (west)
+BR	-0846-06354	America/Porto_Velho	Rondônia
+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
+BT	+2728+08939	Asia/Thimphu
+BY	+5354+02734	Europe/Minsk
+BZ	+1730-08812	America/Belize
+CA	+4734-05243	America/St_Johns	Newfoundland; Labrador (southeast)
+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,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	+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)
+CA	+624900-0920459	America/Rankin_Inlet	Central - NU (central)
+CA	+5024-10439	America/Regina	CST - SK (most areas)
+CA	+5017-10750	America/Swift_Current	CST - SK (midwest)
+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	+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)
+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,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
+CL	-2709-10926	Pacific/Easter	Easter Island
+CN	+3114+12128	Asia/Shanghai	Beijing Time
+CN	+4348+08735	Asia/Urumqi	Xinjiang Time
+CO	+0436-07405	America/Bogota
+CR	+0956-08405	America/Costa_Rica
+CU	+2308-08222	America/Havana
+CV	+1455-02331	Atlantic/Cape_Verde
+CX	-1025+10543	Indian/Christmas
+CY	+3510+03322	Asia/Nicosia	Cyprus (most areas)
+CY	+3507+03357	Asia/Famagusta	Northern Cyprus
+CZ,SK	+5005+01426	Europe/Prague
+DE	+5230+01322	Europe/Berlin	Germany (most areas)
+DK	+5540+01235	Europe/Copenhagen
+DO	+1828-06954	America/Santo_Domingo
+DZ	+3647+00303	Africa/Algiers
+EC	-0210-07950	America/Guayaquil	Ecuador (mainland)
+EC	-0054-08936	Pacific/Galapagos	Galápagos Islands
+EE	+5925+02445	Europe/Tallinn
+EG	+3003+03115	Africa/Cairo
+EH	+2709-01312	Africa/El_Aaiun
+ES	+4024-00341	Europe/Madrid	Spain (mainland)
+ES	+3553-00519	Africa/Ceuta	Ceuta, Melilla
+ES	+2806-01524	Atlantic/Canary	Canary Islands
+FI,AX	+6010+02458	Europe/Helsinki
+FJ	-1808+17825	Pacific/Fiji
+FK	-5142-05751	Atlantic/Stanley
+FM	+0725+15147	Pacific/Chuuk	Chuuk/Truk, Yap
+FM	+0658+15813	Pacific/Pohnpei	Pohnpei/Ponape
+FM	+0519+16259	Pacific/Kosrae	Kosrae
+FO	+6201-00646	Atlantic/Faroe
+FR	+4852+00220	Europe/Paris
+GB,GG,IM,JE	+513030-0000731	Europe/London
+GE	+4143+04449	Asia/Tbilisi
+GF	+0456-05220	America/Cayenne
+GI	+3608-00521	Europe/Gibraltar
+GL	+6411-05144	America/Nuuk	Greenland (most areas)
+GL	+7646-01840	America/Danmarkshavn	National Park (east coast)
+GL	+7029-02158	America/Scoresbysund	Scoresbysund/Ittoqqortoormiit
+GL	+7634-06847	America/Thule	Thule/Pituffik
+GR	+3758+02343	Europe/Athens
+GS	-5416-03632	Atlantic/South_Georgia
+GT	+1438-09031	America/Guatemala
+GU,MP	+1328+14445	Pacific/Guam
+GW	+1151-01535	Africa/Bissau
+GY	+0648-05810	America/Guyana
+HK	+2217+11409	Asia/Hong_Kong
+HN	+1406-08713	America/Tegucigalpa
+HT	+1832-07220	America/Port-au-Prince
+HU	+4730+01905	Europe/Budapest
+ID	-0610+10648	Asia/Jakarta	Java, Sumatra
+ID	-0002+10920	Asia/Pontianak	Borneo (west, central)
+ID	-0507+11924	Asia/Makassar	Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west)
+ID	-0232+14042	Asia/Jayapura	New Guinea (West Papua / Irian Jaya); Malukus/Moluccas
+IE	+5320-00615	Europe/Dublin
+IL	+314650+0351326	Asia/Jerusalem
+IN	+2232+08822	Asia/Kolkata
+IO	-0720+07225	Indian/Chagos
+IQ	+3321+04425	Asia/Baghdad
+IR	+3540+05126	Asia/Tehran
+IS	+6409-02151	Atlantic/Reykjavik
+IT,SM,VA	+4154+01229	Europe/Rome
+JM	+175805-0764736	America/Jamaica
+JO	+3157+03556	Asia/Amman
+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	-0247-17143	Pacific/Kanton	Phoenix Islands
+KI	+0152-15720	Pacific/Kiritimati	Line Islands
+KP	+3901+12545	Asia/Pyongyang
+KR	+3733+12658	Asia/Seoul
+KZ	+4315+07657	Asia/Almaty	Kazakhstan (most areas)
+KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
+KZ	+5312+06337	Asia/Qostanay	Qostanay/Kostanay/Kustanay
+KZ	+5017+05710	Asia/Aqtobe	Aqtöbe/Aktobe
+KZ	+4431+05016	Asia/Aqtau	Mangghystaū/Mankistau
+KZ	+4707+05156	Asia/Atyrau	Atyraū/Atirau/Gur'yev
+KZ	+5113+05121	Asia/Oral	West Kazakhstan
+LB	+3353+03530	Asia/Beirut
+LK	+0656+07951	Asia/Colombo
+LR	+0618-01047	Africa/Monrovia
+LT	+5441+02519	Europe/Vilnius
+LU	+4936+00609	Europe/Luxembourg
+LV	+5657+02406	Europe/Riga
+LY	+3254+01311	Africa/Tripoli
+MA	+3339-00735	Africa/Casablanca
+MC	+4342+00723	Europe/Monaco
+MD	+4700+02850	Europe/Chisinau
+MH	+0709+17112	Pacific/Majuro	Marshall Islands (most areas)
+MH	+0905+16720	Pacific/Kwajalein	Kwajalein
+MM	+1647+09610	Asia/Yangon
+MN	+4755+10653	Asia/Ulaanbaatar	Mongolia (most areas)
+MN	+4801+09139	Asia/Hovd	Bayan-Ölgii, Govi-Altai, Hovd, Uvs, Zavkhan
+MN	+4804+11430	Asia/Choibalsan	Dornod, Sükhbaatar
+MO	+221150+1133230	Asia/Macau
+MQ	+1436-06105	America/Martinique
+MT	+3554+01431	Europe/Malta
+MU	-2010+05730	Indian/Mauritius
+MV	+0410+07330	Indian/Maldives
+MX	+1924-09909	America/Mexico_City	Central Time
+MX	+2105-08646	America/Cancun	Eastern Standard Time - Quintana Roo
+MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatán
+MX	+2540-10019	America/Monterrey	Central Time - Durango; Coahuila, Nuevo León, Tamaulipas (most areas)
+MX	+2550-09730	America/Matamoros	Central Time US - Coahuila, Nuevo León, Tamaulipas (US border)
+MX	+2313-10625	America/Mazatlan	Mountain Time - Baja California Sur, Nayarit, Sinaloa
+MX	+2838-10605	America/Chihuahua	Mountain Time - Chihuahua (most areas)
+MX	+2934-10425	America/Ojinaga	Mountain Time US - Chihuahua (US border)
+MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
+MX	+3232-11701	America/Tijuana	Pacific Time US - Baja California
+MX	+2048-10515	America/Bahia_Banderas	Central Time - Bahía de Banderas
+MY	+0310+10142	Asia/Kuala_Lumpur	Malaysia (peninsula)
+MY	+0133+11020	Asia/Kuching	Sabah, Sarawak
+MZ,BI,BW,CD,MW,RW,ZM,ZW	-2558+03235	Africa/Maputo	Central Africa Time
+NA	-2234+01706	Africa/Windhoek
+NC	-2216+16627	Pacific/Noumea
+NF	-2903+16758	Pacific/Norfolk
+NG,AO,BJ,CD,CF,CG,CM,GA,GQ,NE	+0627+00324	Africa/Lagos	West Africa Time
+NI	+1209-08617	America/Managua
+NL	+5222+00454	Europe/Amsterdam
+NO,SJ	+5955+01045	Europe/Oslo
+NP	+2743+08519	Asia/Kathmandu
+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,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,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,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)
+PT	+3238-01654	Atlantic/Madeira	Madeira Islands
+PT	+3744-02540	Atlantic/Azores	Azores
+PW	+0720+13429	Pacific/Palau
+PY	-2516-05740	America/Asuncion
+QA,BH	+2517+05132	Asia/Qatar
+RE,TF	-2052+05528	Indian/Reunion	Réunion, Crozet, Scattered Islands
+RO	+4426+02606	Europe/Bucharest
+RS,BA,HR,ME,MK,SI	+4450+02030	Europe/Belgrade
+RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
+RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
+# Mention RU and UA alphabetically.  See "territorial claims" above.
+RU,UA	+4457+03406	Europe/Simferopol	Crimea
+RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
+RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
+RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
+RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
+RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
+RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
+RU	+5651+06036	Asia/Yekaterinburg	MSK+02 - Urals
+RU	+5500+07324	Asia/Omsk	MSK+03 - Omsk
+RU	+5502+08255	Asia/Novosibirsk	MSK+04 - Novosibirsk
+RU	+5322+08345	Asia/Barnaul	MSK+04 - Altai
+RU	+5630+08458	Asia/Tomsk	MSK+04 - Tomsk
+RU	+5345+08707	Asia/Novokuznetsk	MSK+04 - Kemerovo
+RU	+5601+09250	Asia/Krasnoyarsk	MSK+04 - Krasnoyarsk area
+RU	+5216+10420	Asia/Irkutsk	MSK+05 - Irkutsk, Buryatia
+RU	+5203+11328	Asia/Chita	MSK+06 - Zabaykalsky
+RU	+6200+12940	Asia/Yakutsk	MSK+06 - Lena River
+RU	+623923+1353314	Asia/Khandyga	MSK+06 - Tomponsky, Ust-Maysky
+RU	+4310+13156	Asia/Vladivostok	MSK+07 - Amur River
+RU	+643337+1431336	Asia/Ust-Nera	MSK+07 - Oymyakonsky
+RU	+5934+15048	Asia/Magadan	MSK+08 - Magadan
+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,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,MY	+0117+10351	Asia/Singapore	Singapore, peninsular Malaysia
+SR	+0550-05510	America/Paramaribo
+SS	+0451+03137	Africa/Juba
+ST	+0020+00644	Africa/Sao_Tome
+SV	+1342-08912	America/El_Salvador
+SY	+3330+03618	Asia/Damascus
+TC	+2128-07108	America/Grand_Turk
+TD	+1207+01503	Africa/Ndjamena
+TF	-492110+0701303	Indian/Kerguelen	Kerguelen, St Paul Island, Amsterdam Island
+TH,KH,LA,VN	+1345+10031	Asia/Bangkok	Indochina (most areas)
+TJ	+3835+06848	Asia/Dushanbe
+TK	-0922-17114	Pacific/Fakaofo
+TL	-0833+12535	Asia/Dili
+TM	+3757+05823	Asia/Ashgabat
+TN	+3648+01011	Africa/Tunis
+TO	-210800-1751200	Pacific/Tongatapu
+TR	+4101+02858	Europe/Istanbul
+TV	-0831+17913	Pacific/Funafuti
+TW	+2503+12130	Asia/Taipei
+UA	+5026+03031	Europe/Kiev	Ukraine (most areas)
+UA	+4837+02218	Europe/Uzhgorod	Transcarpathia
+UA	+4750+03510	Europe/Zaporozhye	Zaporozhye and east Lugansk
+UM	+1917+16637	Pacific/Wake	Wake Island
+US	+404251-0740023	America/New_York	Eastern (most areas)
+US	+421953-0830245	America/Detroit	Eastern - MI (most areas)
+US	+381515-0854534	America/Kentucky/Louisville	Eastern - KY (Louisville area)
+US	+364947-0845057	America/Kentucky/Monticello	Eastern - KY (Wayne)
+US	+394606-0860929	America/Indiana/Indianapolis	Eastern - IN (most areas)
+US	+384038-0873143	America/Indiana/Vincennes	Eastern - IN (Da, Du, K, Mn)
+US	+410305-0863611	America/Indiana/Winamac	Eastern - IN (Pulaski)
+US	+382232-0862041	America/Indiana/Marengo	Eastern - IN (Crawford)
+US	+382931-0871643	America/Indiana/Petersburg	Eastern - IN (Pike)
+US	+384452-0850402	America/Indiana/Vevay	Eastern - IN (Switzerland)
+US	+415100-0873900	America/Chicago	Central (most areas)
+US	+375711-0864541	America/Indiana/Tell_City	Central - IN (Perry)
+US	+411745-0863730	America/Indiana/Knox	Central - IN (Starke)
+US	+450628-0873651	America/Menominee	Central - MI (Wisconsin border)
+US	+470659-1011757	America/North_Dakota/Center	Central - ND (Oliver)
+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,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
+US	+571035-1351807	America/Sitka	Alaska - Sitka area
+US	+550737-1313435	America/Metlakatla	Alaska - Annette Island
+US	+593249-1394338	America/Yakutat	Alaska - Yakutat
+US	+643004-1652423	America/Nome	Alaska (west)
+US	+515248-1763929	America/Adak	Aleutian Islands
+US,UM	+211825-1575130	Pacific/Honolulu	Hawaii
+UY	-345433-0561245	America/Montevideo
+UZ	+3940+06648	Asia/Samarkand	Uzbekistan (west)
+UZ	+4120+06918	Asia/Tashkent	Uzbekistan (east)
+VE	+1030-06656	America/Caracas
+VN	+1045+10640	Asia/Ho_Chi_Minh	Vietnam (south)
+VU	-1740+16825	Pacific/Efate
+WF	-1318-17610	Pacific/Wallis
+WS	-1350-17144	Pacific/Apia
+ZA,LS,SZ	-2615+02800	Africa/Johannesburg

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/debug/.build-id/38/e3b7e0e2a10a41edc9163125934364a9f8bd2e.debug
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/libcctz.so.2.3+git20220321.1.455b5f5
lrwxrwxrwx  root/root   /usr/lib/x86_64-linux-gnu/libcctz.so.2 -> libcctz.so.2.3+git20220321.1.455b5f5

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/debug/.build-id/bf/9b289b261659577da4fa60e9156703d025bebf.debug
-rw-r--r--  root/root   /usr/lib/x86_64-linux-gnu/libcctz.so.2.3+dfsg1
lrwxrwxrwx  root/root   /usr/lib/x86_64-linux-gnu/libcctz.so.2 -> libcctz.so.2.3+dfsg1

No differences were encountered between the control files of package libcctz-dev

No differences were encountered between the control files of package libcctz-doc

No differences were encountered between the control files of package libcctz2

Control files of package libcctz2-dbgsym: lines which differ (wdiff format)

  • Build-Ids: bf9b289b261659577da4fa60e9156703d025bebf 38e3b7e0e2a10a41edc9163125934364a9f8bd2e

More details

Full run details