[libcxx-commits] [libcxx] Reverts around time_zone (PR #95058)

Florian Mayer via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 10 16:23:17 PDT 2024


https://github.com/fmayer created https://github.com/llvm/llvm-project/pull/95058

I intend to submit those as separate changes, not as one squashed change.

>From b510fb2850e77eca7e89cb6f19edfd51fc878dce Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:04:34 -0700
Subject: [PATCH 1/6] Revert "[libc++][TZDB] Implements zoned_traits. (#91059)"

This reverts commit 151bd7cab4fc5223673c71cdbd18980bcf2f5f4d.
---
 libcxx/include/CMakeLists.txt                 |  1 -
 libcxx/include/__chrono/zoned_time.h          | 55 -------------------
 libcxx/include/chrono                         |  4 --
 libcxx/include/module.modulemap               |  1 -
 libcxx/modules/std/chrono.inc                 |  3 +-
 .../diagnostics/chrono.nodiscard.verify.cpp   |  6 --
 .../const_time_zone_default_zone.pass.cpp     | 36 ------------
 .../const_time_zone_locate_zone.pass.cpp      | 45 ---------------
 .../types.compile.pass.cpp                    | 33 -----------
 9 files changed, 2 insertions(+), 182 deletions(-)
 delete mode 100644 libcxx/include/__chrono/zoned_time.h
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d65b7ce782ebd..cbbcc74e21b44 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -277,7 +277,6 @@ set(files
   __chrono/year_month.h
   __chrono/year_month_day.h
   __chrono/year_month_weekday.h
-  __chrono/zoned_time.h
   __compare/common_comparison_category.h
   __compare/compare_partial_order_fallback.h
   __compare/compare_strong_order_fallback.h
diff --git a/libcxx/include/__chrono/zoned_time.h b/libcxx/include/__chrono/zoned_time.h
deleted file mode 100644
index c6084426ad72b..0000000000000
--- a/libcxx/include/__chrono/zoned_time.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
-
-#ifndef _LIBCPP___CHRONO_ZONED_TIME_H
-#define _LIBCPP___CHRONO_ZONED_TIME_H
-
-#include <version>
-// Enable the contents of the header only when libc++ was built with experimental features enabled.
-#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
-
-#  include <__chrono/time_zone.h>
-#  include <__chrono/tzdb_list.h>
-#  include <__config>
-#  include <__fwd/string_view.h>
-
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#  if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&   \
-      !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-
-namespace chrono {
-
-template <class>
-struct zoned_traits {};
-
-template <>
-struct zoned_traits<const time_zone*> {
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* default_zone() { return chrono::locate_zone("UTC"); }
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* locate_zone(string_view __name) {
-    return chrono::locate_zone(__name);
-  }
-};
-
-} // namespace chrono
-
-#  endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM)
-         // && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
-
-#endif // _LIBCPP___CHRONO_ZONED_TIME_H
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index c1a92595ff1f5..4d47dc57ba654 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -786,9 +786,6 @@ class time_zone {
 bool operator==(const time_zone& x, const time_zone& y) noexcept;                // C++20
 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;    // C++20
 
-// [time.zone.zonedtraits], class template zoned_traits
-template<class T> struct zoned_traits;                                           // C++20
-
 // [time.zone.leap], leap second support
 class leap_second {                                                              // C++20
 public:
@@ -962,7 +959,6 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 #    include <__chrono/time_zone_link.h>
 #    include <__chrono/tzdb.h>
 #    include <__chrono/tzdb_list.h>
-#    include <__chrono/zoned_time.h>
 #  endif
 
 #endif
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 892d2c6b4af3c..e03ea989eb371 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1159,7 +1159,6 @@ module std_private_chrono_year                   [system] { header "__chrono/yea
 module std_private_chrono_year_month             [system] { header "__chrono/year_month.h" }
 module std_private_chrono_year_month_day         [system] { header "__chrono/year_month_day.h" }
 module std_private_chrono_year_month_weekday     [system] { header "__chrono/year_month_weekday.h" }
-module std_private_chrono_zoned_time             [system] { header "__chrono/zoned_time.h" }
 
 module std_private_compare_common_comparison_category     [system] { header "__compare/common_comparison_category.h" }
 module std_private_compare_compare_partial_order_fallback [system] { header "__compare/compare_partial_order_fallback.h" }
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index 87e32afbe4bdc..f12c2425592e0 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -227,10 +227,11 @@ export namespace std {
     using std::chrono::choose;
     using std::chrono::time_zone;
 
+#    if 0
+
     // [time.zone.zonedtraits], class template zoned_traits
     using std::chrono::zoned_traits;
 
-#    if 0
     // [time.zone.zonedtime], class template zoned_time
     using std::chrono::zoned_time;
 
diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 6fed41bdb43ed..cba7916ff2c64 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -72,10 +72,4 @@ void test() {
     leap.date();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     leap.value(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
-
-  {
-    using t = std::chrono::zoned_traits<const std::chrono::time_zone*>;
-    t::default_zone();  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    t::locate_zone(""); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-  }
 }
diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp
deleted file mode 100644
index c6527094bb621..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_default_zone.pass.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// template<> struct zoned_traits<const time_zone*>;
-
-// static const time_zone* default_zone();
-
-#include <chrono>
-#include <cassert>
-
-int main(int, char**) {
-  std::same_as<const std::chrono::time_zone*> decltype(auto) tz =
-      std::chrono::zoned_traits<const std::chrono::time_zone*>::default_zone();
-  assert(tz);
-
-  // The time zone "UTC" can be a link, this means tz->name() can be something
-  // differently. For example, "Etc/UTC". Instead validate whether same time
-  // zone is returned by comparing the addresses.
-  const std::chrono::time_zone* expected = std::chrono::locate_zone("UTC");
-  assert(tz == expected);
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp
deleted file mode 100644
index 1c8184455f23c..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/const_time_zone_locate_zone.pass.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// template<> struct zoned_traits<const time_zone*>;
-
-// static const time_zone* locate_zone(string_view name);
-
-#include <chrono>
-#include <cassert>
-#include <concepts>
-
-#include "assert_macros.h"
-
-static void test(std::string_view name) {
-  std::same_as<const std::chrono::time_zone*> decltype(auto) tz =
-      std::chrono::zoned_traits<const std::chrono::time_zone*>::locate_zone(name);
-
-  const std::chrono::time_zone* expected = std::chrono::locate_zone(name);
-  assert(tz == expected);
-}
-
-int main(int, char**) {
-  test("UTC");
-  test("Europe/Berlin");
-  test("Asia/Hong_Kong");
-
-  TEST_THROWS_TYPE(std::runtime_error,
-                   TEST_IGNORE_NODISCARD std::chrono::zoned_traits<const std::chrono::time_zone*>::locate_zone(
-                       "there_is_no_time_zone_with_this_name"));
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp
deleted file mode 100644
index 6e3410795c824..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// template<class T> struct zoned_traits {};
-//
-// A specialization for const time_zone* is provided by the implementation:
-// template<> struct zoned_traits<const time_zone*> { ... }
-
-#include <chrono>
-#include <type_traits>
-
-// This test test whether non-specialized versions exhibit the expected
-// behavior. (Note these specializations are not really useful.)
-static_assert(std::is_trivial_v<std::chrono::zoned_traits<int>>);
-static_assert(std::is_trivial_v<std::chrono::zoned_traits<float>>);
-static_assert(std::is_trivial_v<std::chrono::zoned_traits<void*>>);
-
-struct foo {};
-static_assert(std::is_empty_v<std::chrono::zoned_traits<foo>>);
-static_assert(std::is_trivial_v<std::chrono::zoned_traits<foo>>);

>From 4067300c47dfb99f4a19408d39e5ed4f43d194de Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:05:18 -0700
Subject: [PATCH 2/6] Revert "[libc++][TZDB] Implements time_zone::to_local.
 (#91003)"

This reverts commit da03175cae73ba9c564f0d338e9c0f7c6f730555.
---
 libcxx/include/__chrono/time_zone.h           | 18 -----
 libcxx/include/chrono                         |  4 --
 .../assert.to_local.pass.cpp                  | 40 -----------
 .../time.zone.members/to_local.pass.cpp       | 68 -------------------
 4 files changed, 130 deletions(-)
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_local.pass.cpp

diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h
index de11dac1eef0c..89ab6d1f21102 100644
--- a/libcxx/include/__chrono/time_zone.h
+++ b/libcxx/include/__chrono/time_zone.h
@@ -129,24 +129,6 @@ class _LIBCPP_AVAILABILITY_TZDB time_zone {
     return {};
   }
 
-  template <class _Duration>
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time<common_type_t<_Duration, seconds>>
-  to_local(const sys_time<_Duration>& __time) const {
-    using _Dp = common_type_t<_Duration, seconds>;
-
-    sys_info __info = get_info(__time);
-
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.offset >= chrono::seconds{0} || __time.time_since_epoch() >= _Dp::min() - __info.offset,
-        "cannot convert the system time; it would be before the minimum local clock value");
-
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.offset <= chrono::seconds{0} || __time.time_since_epoch() <= _Dp::max() - __info.offset,
-        "cannot convert the system time; it would be after the maximum local clock value");
-
-    return local_time<_Dp>{__time.time_since_epoch() + __info.offset};
-  }
-
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
 
 private:
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 4d47dc57ba654..78e885f6ca373 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -778,10 +778,6 @@ class time_zone {
   template<class Duration>
   sys_time<common_type_t<Duration, seconds>>
     to_sys(const local_time<Duration>& tp, choose z) const;
-
-  template<class Duration>
-  local_time<common_type_t<Duration, seconds>>
-    to_local(const sys_time<Duration>& tp) const;
 };
 bool operator==(const time_zone& x, const time_zone& y) noexcept;                // C++20
 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;    // C++20
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
deleted file mode 100644
index d9ca1c80751cc..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_local.pass.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// template <class _Duration>
-// local_time<common_type_t<Duration, seconds>>
-//   to_local(const sys_time<Duration>& tp) const;
-
-#include <chrono>
-
-#include "check_assertion.h"
-
-// Tests values that cannot be converted. To make sure the test is does not depend on changes
-// in the database it uses a time zone with a fixed offset.
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(std::chrono::locate_zone("Etc/GMT+1")->to_local(std::chrono::sys_seconds::min()),
-                             "cannot convert the system time; it would be before the minimum local clock value");
-
-  // TODO TZDB look why std::chrono::sys_seconds::max()  fails
-  TEST_LIBCPP_ASSERT_FAILURE(
-      std::chrono::locate_zone("Etc/GMT-1")->to_local(std::chrono::sys_seconds::max() - std::chrono::seconds(1)),
-      "cannot convert the system time; it would be after the maximum local clock value");
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_local.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_local.pass.cpp
deleted file mode 100644
index 28d61455710cb..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_local.pass.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class time_zone;
-
-// template <class _Duration>
-// local_time<common_type_t<Duration, seconds>>
-//   to_local(const sys_time<Duration>& tp) const;
-
-#include <chrono>
-#include <format>
-#include <cassert>
-#include <string_view>
-
-#include "test_macros.h"
-#include "assert_macros.h"
-#include "concat_macros.h"
-
-int main(int, char**) {
-  // To make sure the test does not depend on changes in the database it uses a
-  // time zone with a fixed offset.
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");
-
-  assert(tz->to_local(std::chrono::sys_time<std::chrono::nanoseconds>{-1ns}) ==
-         std::chrono::local_time<std::chrono::nanoseconds>{-1ns - 1h});
-
-  assert(tz->to_local(std::chrono::sys_time<std::chrono::microseconds>{0us}) ==
-         std::chrono::local_time<std::chrono::microseconds>{0us - 1h});
-
-  assert(tz->to_local(
-             std::chrono::sys_time<std::chrono::seconds>{std::chrono::sys_days{std::chrono::January / 1 / -21970}}) ==
-         std::chrono::local_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch() - 1h});
-
-  assert(
-      tz->to_local(std::chrono::sys_time<std::chrono::days>{std::chrono::sys_days{std::chrono::January / 1 / 21970}}) ==
-      std::chrono::local_time<std::chrono::seconds>{
-          (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch() - 1h});
-
-  assert(tz->to_local(std::chrono::sys_time<std::chrono::weeks>{}) ==
-         std::chrono::local_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() - 1h});
-
-  assert(tz->to_local(std::chrono::sys_time<std::chrono::months>{}) ==
-         std::chrono::local_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() - 1h});
-
-  assert(tz->to_local(std::chrono::sys_time<std::chrono::years>{}) ==
-         std::chrono::local_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() - 1h});
-
-  return 0;
-}

>From 7eaf9938acd4649f011d65031ac435b97eba074c Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:05:45 -0700
Subject: [PATCH 3/6] Revert "[libc++][TZDB] Implements time_zone::to_sys.
 (#90901)"

This reverts commit 87cedbec1cce1cbfc6ad15ae9b88e3481ba9eead.
---
 libcxx/include/__chrono/time_zone.h           |  32 ----
 libcxx/include/chrono                         |   4 -
 libcxx/modules/std/chrono.inc                 |   3 +
 .../diagnostics/chrono.nodiscard.verify.cpp   |   3 -
 .../time.zone.timezone/choose.pass.cpp        |  37 -----
 .../assert.to_sys_choose.pass.cpp             |  41 -----
 .../time.zone.members/to_sys_choose.pass.cpp  | 147 ------------------
 7 files changed, 3 insertions(+), 264 deletions(-)
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.timezone/choose.pass.cpp
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys_choose.pass.cpp

diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h
index 89ab6d1f21102..b4069823dbe74 100644
--- a/libcxx/include/__chrono/time_zone.h
+++ b/libcxx/include/__chrono/time_zone.h
@@ -42,8 +42,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace chrono {
 
-enum class choose { earliest, latest };
-
 class _LIBCPP_AVAILABILITY_TZDB time_zone {
   _LIBCPP_HIDE_FROM_ABI time_zone() = default;
 
@@ -99,36 +97,6 @@ class _LIBCPP_AVAILABILITY_TZDB time_zone {
     return {};
   }
 
-  template <class _Duration>
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>>
-  to_sys(const local_time<_Duration>& __time, choose __z) const {
-    local_info __info = get_info(__time);
-    switch (__info.result) {
-    case local_info::unique:
-    case local_info::nonexistent: // first and second are the same
-      return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
-
-    case local_info::ambiguous:
-      switch (__z) {
-      case choose::earliest:
-        return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
-
-      case choose::latest:
-        return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.second.offset};
-
-        // Note a value out of bounds is not specified.
-      }
-    }
-
-    // TODO TZDB The standard does not specify anything in these cases.
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
-
-    return {};
-  }
-
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
 
 private:
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 78e885f6ca373..46bca597ee1fd 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -774,10 +774,6 @@ class time_zone {
   template<class Duration>
   sys_time<common_type_t<Duration, seconds>>
     to_sys(const local_time<Duration>& tp) const;
-
-  template<class Duration>
-  sys_time<common_type_t<Duration, seconds>>
-    to_sys(const local_time<Duration>& tp, choose z) const;
 };
 bool operator==(const time_zone& x, const time_zone& y) noexcept;                // C++20
 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;    // C++20
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index f12c2425592e0..bd3b6c3c12f29 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -223,8 +223,11 @@ export namespace std {
 #  if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&                            \
       !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 
+#    if 0
     // [time.zone.timezone], class time_zone
     using std::chrono::choose;
+#    endif // if 0
+
     using std::chrono::time_zone;
 
 #    if 0
diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index cba7916ff2c64..fea1e4417cc12 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -49,12 +49,9 @@ void test() {
   {
     std::chrono::sys_seconds s{};
     std::chrono::local_seconds l{};
-    std::chrono::choose z = std::chrono::choose::earliest;
     tz.name();           // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     tz.get_info(s);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     tz.get_info(l);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    tz.to_sys(l);        // not nodiscard
-    tz.to_sys(l, z);     // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     operator==(tz, tz);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     operator<=>(tz, tz); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/choose.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/choose.pass.cpp
deleted file mode 100644
index 23ef9c8480960..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/choose.pass.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// enum class choose;
-
-#include <chrono>
-#include <type_traits>
-#include <cassert>
-
-#include "test_macros.h"
-
-int main(int, char**) {
-  using E = std::chrono::choose;
-  static_assert(std::is_enum_v<E>);
-
-  // Check that E is a scoped enum by checking for conversions.
-  using UT = std::underlying_type_t<E>;
-  static_assert(!std::is_convertible_v<E, UT>);
-
-  [[maybe_unused]] const E& early = E::earliest;
-  [[maybe_unused]] const E& late  = E::latest;
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
deleted file mode 100644
index 65429345ae794..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys_choose.pass.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-
-// <chrono>
-
-// template <class _Duration>
-//   sys_time<common_type_t<Duration, seconds>>
-//     to_sys(const local_time<Duration>& tp, choose z) const;
-
-#include <chrono>
-
-#include "check_assertion.h"
-
-// Tests values that cannot be converted. To make sure the test is does not depend on changes
-// in the database it uses a time zone with a fixed offset.
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(
-      std::chrono::locate_zone("Etc/GMT-1")->to_sys(std::chrono::local_seconds::min(), std::chrono::choose::earliest),
-      "cannot convert the local time; it would be before the minimum system clock value");
-
-  // TODO TZDB look why std::chrono::local_seconds::max()  fails
-  TEST_LIBCPP_ASSERT_FAILURE(
-      std::chrono::locate_zone("Etc/GMT+1")
-          ->to_sys(std::chrono::local_seconds::max() - std::chrono::seconds(1), std::chrono::choose::latest),
-      "cannot convert the local time; it would be after the maximum system clock value");
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys_choose.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys_choose.pass.cpp
deleted file mode 100644
index bad4ef352e9b9..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys_choose.pass.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class time_zone;
-
-// template <class _Duration>
-//   sys_time<common_type_t<Duration, seconds>>
-//     to_sys(const local_time<Duration>& tp, choose z) const;
-
-#include <chrono>
-#include <format>
-#include <cassert>
-#include <string_view>
-
-#include "test_macros.h"
-
-// Tests unique conversions. To make sure the test is does not depend on changes
-// in the database it uses a time zone with a fixed offset.
-static void test_unique() {
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::nanoseconds>{-1ns}, std::chrono::choose::earliest) ==
-         std::chrono::sys_time<std::chrono::nanoseconds>{-1ns + 1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::microseconds>{0us}, std::chrono::choose::latest) ==
-         std::chrono::sys_time<std::chrono::microseconds>{1h});
-
-  assert(tz->to_sys(
-             std::chrono::local_time<std::chrono::seconds>{
-                 (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},
-             std::chrono::choose::earliest) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch() + 1h});
-
-  // sys_time<common_type_t<Duration, seconds>> is seconds for the larger types
-  assert(tz->to_sys(
-             std::chrono::local_time<std::chrono::days>{
-                 (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},
-             std::chrono::choose::latest) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch() + 1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::weeks>{}, std::chrono::choose::earliest) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});
-
-  // Note months and years cannot be streamed; however these functions don't
-  // throw an exception and thus can be used.
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::months>{}, std::chrono::choose::latest) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::years>{}, std::chrono::choose::earliest) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});
-}
-
-// Tests non-existant conversions.
-static void test_nonexistent() {
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");
-
-  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap
-  // ...
-  // 1 DE CE%sT 1980
-  // 1 E CE%sT
-  //
-  // ...
-  // R E 1981 ma - Mar lastSu 1u 1 S
-  // R E 1996 ma - O lastSu 1u 0 -
-
-  // Pick an historic date where it's well known what the time zone rules were.
-  // This makes it unlikely updates to the database change these rules.
-  std::chrono::local_time<std::chrono::seconds> time{
-      (std::chrono::sys_days{std::chrono::March / 30 / 1986} + 2h + 30min).time_since_epoch()};
-
-  std::chrono::sys_seconds expected{time.time_since_epoch() - 1h};
-
-  // Validates whether the database did not change.
-  std::chrono::local_info info = tz->get_info(time);
-  assert(info.result == std::chrono::local_info::nonexistent);
-
-  assert(tz->to_sys(time + 0ns, std::chrono::choose::earliest) == expected);
-  assert(tz->to_sys(time + 0us, std::chrono::choose::latest) == expected);
-  assert(tz->to_sys(time + 0ms, std::chrono::choose::earliest) == expected);
-  assert(tz->to_sys(time + 0s, std::chrono::choose::latest) == expected);
-}
-
-// Tests ambiguous conversions.
-static void test_ambiguous() {
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");
-
-  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap
-  // ...
-  // 1 DE CE%sT 1980
-  // 1 E CE%sT
-  //
-  // ...
-  // R E 1981 ma - Mar lastSu 1u 1 S
-  // R E 1996 ma - O lastSu 1u 0 -
-
-  // Pick an historic date where it's well known what the time zone rules were.
-  // This makes it unlikely updates to the database change these rules.
-  std::chrono::local_time<std::chrono::seconds> time{
-      (std::chrono::sys_days{std::chrono::September / 28 / 1986} + 2h + 30min).time_since_epoch()};
-
-  std::chrono::sys_seconds earlier{time.time_since_epoch() - 2h};
-  std::chrono::sys_seconds later{time.time_since_epoch() - 1h};
-
-  // Validates whether the database did not change.
-  std::chrono::local_info info = tz->get_info(time);
-  assert(info.result == std::chrono::local_info::ambiguous);
-
-  assert(tz->to_sys(time + 0ns, std::chrono::choose::earliest) == earlier);
-  assert(tz->to_sys(time + 0us, std::chrono::choose::latest) == later);
-  assert(tz->to_sys(time + 0ms, std::chrono::choose::earliest) == earlier);
-  assert(tz->to_sys(time + 0s, std::chrono::choose::latest) == later);
-}
-
-// This test does the basic validations of this function. The library function
-// uses `local_info get_info(const local_time<Duration>& tp)` as implementation
-// detail. The get_info function does extensive testing of the data.
-int main(int, char**) {
-  test_unique();
-  test_nonexistent();
-  test_ambiguous();
-
-  return 0;
-}

>From 9791e739193e654da9095d69b479a257464c707a Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:06:07 -0700
Subject: [PATCH 4/6] Revert "[libc++][TZDB] Implements time_zone::to_sys.
 (#90394)"

This reverts commit 77116bd7d2682dde2bdfc6c4b96d036ffa7bc3b6.
---
 libcxx/include/CMakeLists.txt                 |   1 -
 libcxx/include/__chrono/exception.h           | 129 ----------
 libcxx/include/__chrono/time_zone.h           |  27 --
 libcxx/include/chrono                         |   9 -
 libcxx/include/module.modulemap               |   6 +-
 libcxx/modules/std/chrono.inc                 |   7 +-
 libcxx/src/CMakeLists.txt                     |   3 -
 libcxx/src/chrono_exception.cpp               |  22 --
 .../assert.ctor.pass.cpp                      |  53 ----
 .../assert.ctor.pass.cpp                      |  53 ----
 .../time.zone.members/assert.to_sys.pass.cpp  |  39 ---
 .../test/libcxx/transitive_includes/cxx03.csv |   3 +
 .../test/libcxx/transitive_includes/cxx11.csv |   3 +
 .../test/libcxx/transitive_includes/cxx14.csv |   3 +
 .../test/libcxx/transitive_includes/cxx17.csv |   3 +
 .../test/libcxx/transitive_includes/cxx20.csv |   9 +-
 .../test/libcxx/transitive_includes/cxx23.csv |  12 +-
 .../test/libcxx/transitive_includes/cxx26.csv |  35 ++-
 .../time.zone.exception.ambig/ctor.pass.cpp   | 171 -------------
 .../time.zone.exception.ambig/types.pass.cpp  |  50 ----
 .../ctor.pass.cpp                             | 172 -------------
 .../types.pass.cpp                            |  50 ----
 .../time.zone.members/to_sys.pass.cpp         | 237 ------------------
 23 files changed, 70 insertions(+), 1027 deletions(-)
 delete mode 100644 libcxx/include/__chrono/exception.h
 delete mode 100644 libcxx/src/chrono_exception.cpp
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
 delete mode 100644 libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/ctor.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/types.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/ctor.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/types.pass.cpp
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cbbcc74e21b44..cfe1f44777bca 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -250,7 +250,6 @@ set(files
   __chrono/convert_to_tm.h
   __chrono/day.h
   __chrono/duration.h
-  __chrono/exception.h
   __chrono/file_clock.h
   __chrono/formatter.h
   __chrono/hh_mm_ss.h
diff --git a/libcxx/include/__chrono/exception.h b/libcxx/include/__chrono/exception.h
deleted file mode 100644
index 75fd0615b7e08..0000000000000
--- a/libcxx/include/__chrono/exception.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
-
-#ifndef _LIBCPP___CHRONO_EXCEPTION_H
-#define _LIBCPP___CHRONO_EXCEPTION_H
-
-#include <version>
-// Enable the contents of the header only when libc++ was built with experimental features enabled.
-#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
-
-#  include <__chrono/calendar.h>
-#  include <__chrono/local_info.h>
-#  include <__chrono/time_point.h>
-#  include <__config>
-#  include <__configuration/availability.h>
-#  include <__verbose_abort>
-#  include <format>
-#  include <stdexcept>
-#  include <string>
-
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#  if _LIBCPP_STD_VER >= 20
-
-namespace chrono {
-
-class nonexistent_local_time : public runtime_error {
-public:
-  template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI nonexistent_local_time(const local_time<_Duration>& __time, const local_info& __info)
-      : runtime_error{__create_message(__time, __info)} {
-    // [time.zone.exception.nonexist]/2
-    //   Preconditions: i.result == local_info::nonexistent is true.
-    // The value of __info.result is not used.
-    _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::nonexistent,
-                            "creating an nonexistent_local_time from a local_info that is not non-existent");
-  }
-
-  _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~nonexistent_local_time() override; // exported as key function
-
-private:
-  template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) {
-    return std::format(
-        R"({} is in a gap between
-{} {} and
-{} {} which are both equivalent to
-{} UTC)",
-        __time,
-        local_seconds{__info.first.end.time_since_epoch()} + __info.first.offset,
-        __info.first.abbrev,
-        local_seconds{__info.second.begin.time_since_epoch()} + __info.second.offset,
-        __info.second.abbrev,
-        __info.first.end);
-  }
-};
-
-template <class _Duration>
-_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_nonexistent_local_time(
-    [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) {
-#    ifndef _LIBCPP_HAS_NO_EXCEPTIONS
-  throw nonexistent_local_time(__time, __info);
-#    else
-  _LIBCPP_VERBOSE_ABORT("nonexistent_local_time was thrown in -fno-exceptions mode");
-#    endif
-}
-
-class ambiguous_local_time : public runtime_error {
-public:
-  template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI ambiguous_local_time(const local_time<_Duration>& __time, const local_info& __info)
-      : runtime_error{__create_message(__time, __info)} {
-    // [time.zone.exception.ambig]/2
-    //   Preconditions: i.result == local_info::ambiguous is true.
-    // The value of __info.result is not used.
-    _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::ambiguous,
-                            "creating an ambiguous_local_time from a local_info that is not ambiguous");
-  }
-
-  _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~ambiguous_local_time() override; // exported as key function
-
-private:
-  template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) {
-    return std::format(
-        // There are two spaces after the full-stop; this has been verified
-        // in the sources of the Standard.
-        R"({0} is ambiguous.  It could be
-{0} {1} == {2} UTC or
-{0} {3} == {4} UTC)",
-        __time,
-        __info.first.abbrev,
-        __time - __info.first.offset,
-        __info.second.abbrev,
-        __time - __info.second.offset);
-  }
-};
-
-template <class _Duration>
-_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_ambiguous_local_time(
-    [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) {
-#    ifndef _LIBCPP_HAS_NO_EXCEPTIONS
-  throw ambiguous_local_time(__time, __info);
-#    else
-  _LIBCPP_VERBOSE_ABORT("ambiguous_local_time was thrown in -fno-exceptions mode");
-#    endif
-}
-
-} // namespace chrono
-
-#  endif // _LIBCPP_STD_VER >= 20
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
-
-#endif // _LIBCPP___CHRONO_EXCEPTION_H
diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h
index b4069823dbe74..e28c9189c381b 100644
--- a/libcxx/include/__chrono/time_zone.h
+++ b/libcxx/include/__chrono/time_zone.h
@@ -18,14 +18,12 @@
 
 #  include <__chrono/calendar.h>
 #  include <__chrono/duration.h>
-#  include <__chrono/exception.h>
 #  include <__chrono/local_info.h>
 #  include <__chrono/sys_info.h>
 #  include <__chrono/system_clock.h>
 #  include <__compare/strong_order.h>
 #  include <__config>
 #  include <__memory/unique_ptr.h>
-#  include <__type_traits/common_type.h>
 #  include <string_view>
 
 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -72,31 +70,6 @@ class _LIBCPP_AVAILABILITY_TZDB time_zone {
     return __get_info(chrono::time_point_cast<seconds>(__time));
   }
 
-  // We don't apply nodiscard here since this function throws on many inputs,
-  // so it could be used as a validation.
-  template <class _Duration>
-  _LIBCPP_HIDE_FROM_ABI sys_time<common_type_t<_Duration, seconds>> to_sys(const local_time<_Duration>& __time) const {
-    local_info __info = get_info(__time);
-    switch (__info.result) {
-    case local_info::unique:
-      return sys_time<common_type_t<_Duration, seconds>>{__time.time_since_epoch() - __info.first.offset};
-
-    case local_info::nonexistent:
-      chrono::__throw_nonexistent_local_time(__time, __info);
-
-    case local_info::ambiguous:
-      chrono::__throw_ambiguous_local_time(__time, __info);
-    }
-
-    // TODO TZDB The Standard does not specify anything in these cases.
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value");
-    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
-        __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value");
-
-    return {};
-  }
-
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
 
 private:
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 46bca597ee1fd..4d8398af1a108 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -724,10 +724,6 @@ const time_zone* current_zone()
 const tzdb& reload_tzdb();                                                       // C++20
 string remote_version();                                                         // C++20
 
-// [time.zone.exception], exception classes
-class nonexistent_local_time;                                                    // C++20
-class ambiguous_local_time;                                                      // C++20
-
 // [time.zone.info], information classes
 struct sys_info {                                                                // C++20
   sys_seconds   begin;
@@ -770,10 +766,6 @@ class time_zone {
 
   template<class Duration>
   local_info get_info(const local_time<Duration>& tp) const;
-
-  template<class Duration>
-  sys_time<common_type_t<Duration, seconds>>
-    to_sys(const local_time<Duration>& tp) const;
 };
 bool operator==(const time_zone& x, const time_zone& y) noexcept;                // C++20
 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;    // C++20
@@ -923,7 +915,6 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 #if _LIBCPP_STD_VER >= 20
 #  include <__chrono/calendar.h>
 #  include <__chrono/day.h>
-#  include <__chrono/exception.h>
 #  include <__chrono/hh_mm_ss.h>
 #  include <__chrono/literals.h>
 #  include <__chrono/local_info.h>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index e03ea989eb371..48391b2a12095 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1101,7 +1101,6 @@ module std_private_chrono_duration               [system] {
   header "__chrono/duration.h"
   export std_private_type_traits_is_convertible
 }
-module std_private_chrono_exception              [system] { header "__chrono/exception.h" }
 module std_private_chrono_file_clock             [system] { header "__chrono/file_clock.h" }
 module std_private_chrono_formatter              [system] {
   header "__chrono/formatter.h"
@@ -1114,10 +1113,7 @@ module std_private_chrono_high_resolution_clock  [system] {
 }
 module std_private_chrono_leap_second            [system] { header "__chrono/leap_second.h" }
 module std_private_chrono_literals               [system] { header "__chrono/literals.h" }
-module std_private_chrono_local_info             [system] {
-  header "__chrono/local_info.h"
-  export std_private_chrono_sys_info
-}
+module std_private_chrono_local_info             [system] { header "__chrono/local_info.h" }
 module std_private_chrono_month                  [system] { header "__chrono/month.h" }
 module std_private_chrono_month_weekday          [system] { header "__chrono/month_weekday.h" }
 module std_private_chrono_monthday               [system] { header "__chrono/monthday.h" }
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index bd3b6c3c12f29..813322a1797f6 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -209,12 +209,13 @@ export namespace std {
     using std::chrono::reload_tzdb;
     using std::chrono::remote_version;
 
-#  endif //  !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&
-         //  !defined(_LIBCPP_HAS_NO_LOCALIZATION)
-
+#    if 0
     // [time.zone.exception], exception classes
     using std::chrono::ambiguous_local_time;
     using std::chrono::nonexistent_local_time;
+#    endif // if 0
+#  endif   //  !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) &&
+           //  !defined(_LIBCPP_HAS_NO_LOCALIZATION)
 
     // [time.zone.info], information classes
     using std::chrono::local_info;
diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 9e6c70335a794..65e6ce2c4da43 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -340,9 +340,6 @@ if (LIBCXX_ENABLE_LOCALIZATION AND LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_ENABLE_TI
     include/tzdb/types_private.h
     include/tzdb/tzdb_list_private.h
     include/tzdb/tzdb_private.h
-    # TODO TZDB The exception could be moved in chrono once the TZDB library
-    # is no longer experimental.
-    chrono_exception.cpp
     time_zone.cpp
     tzdb.cpp
     tzdb_list.cpp
diff --git a/libcxx/src/chrono_exception.cpp b/libcxx/src/chrono_exception.cpp
deleted file mode 100644
index bea2ad110310a..0000000000000
--- a/libcxx/src/chrono_exception.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include <chrono>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-namespace chrono {
-
-_LIBCPP_AVAILABILITY_TZDB
-_LIBCPP_EXPORTED_FROM_ABI nonexistent_local_time::~nonexistent_local_time() = default; // key function
-_LIBCPP_AVAILABILITY_TZDB
-_LIBCPP_EXPORTED_FROM_ABI ambiguous_local_time::~ambiguous_local_time() = default; // key function
-
-} // namespace chrono
-
-_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
deleted file mode 100644
index 73e6bf2846f0e..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.ambig/assert.ctor.pass.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-
-// <chrono>
-
-//  class ambiguous_local_time
-//
-//  template<class Duration>
-//    ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
-
-#include <chrono>
-
-#include "check_assertion.h"
-
-// [time.zone.exception.ambig]/2
-//   Preconditions: i.result == local_info::ambiguous is true.
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::ambiguous_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{-1, //  this is not one of the "named" result values
-                                  std::chrono::sys_info{},
-                                  std::chrono::sys_info{}}}),
-      "creating an ambiguous_local_time from a local_info that is not ambiguous");
-
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::ambiguous_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{std::chrono::local_info::unique, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
-      "creating an ambiguous_local_time from a local_info that is not ambiguous");
-
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::ambiguous_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{
-              std::chrono::local_info::nonexistent, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
-      "creating an ambiguous_local_time from a local_info that is not ambiguous");
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
deleted file mode 100644
index fdd9f79958f98..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.exception/time.zone.exception.nonexist/assert.ctor.pass.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-
-// <chrono>
-
-//  class nonexistent_local_time
-//
-//  template<class Duration>
-//    nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
-
-#include <chrono>
-
-#include "check_assertion.h"
-
-// [time.zone.exception.nonexist]/2
-//   Preconditions: i.result == local_info::nonexistent is true.
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::nonexistent_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{-1, //  this is not one of the "named" result values
-                                  std::chrono::sys_info{},
-                                  std::chrono::sys_info{}}}),
-      "creating an nonexistent_local_time from a local_info that is not non-existent");
-
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::nonexistent_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{std::chrono::local_info::unique, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
-      "creating an nonexistent_local_time from a local_info that is not non-existent");
-
-  TEST_LIBCPP_ASSERT_FAILURE(
-      (std::chrono::nonexistent_local_time{
-          std::chrono::local_seconds{},
-          std::chrono::local_info{
-              std::chrono::local_info::ambiguous, std::chrono::sys_info{}, std::chrono::sys_info{}}}),
-      "creating an nonexistent_local_time from a local_info that is not non-existent");
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
deleted file mode 100644
index 3a2ff00088676..0000000000000
--- a/libcxx/test/libcxx/time/time.zone/time.zone.timezone/time.zone.members/assert.to_sys.pass.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: has-unix-headers
-// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
-// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-
-// <chrono>
-
-// template <class _Duration>
-//   sys_time<common_type_t<Duration, seconds>>
-//     to_sys(const local_time<Duration>& tp) const;
-
-#include <chrono>
-
-#include "check_assertion.h"
-
-// Tests values that cannot be converted. To make sure the test is does not depend on changes
-// in the database it uses a time zone with a fixed offset.
-int main(int, char**) {
-  TEST_LIBCPP_ASSERT_FAILURE(std::chrono::locate_zone("Etc/GMT-1")->to_sys(std::chrono::local_seconds::min()),
-                             "cannot convert the local time; it would be before the minimum system clock value");
-
-  // TODO TZDB look why std::chrono::local_seconds::max()  fails
-  TEST_LIBCPP_ASSERT_FAILURE(
-      std::chrono::locate_zone("Etc/GMT+1")->to_sys(std::chrono::local_seconds::max() - std::chrono::seconds(1)),
-      "cannot convert the local time; it would be after the maximum system clock value");
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index b0431d9b2b551..92601fab5b773 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -187,6 +187,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index 6fc8fe5858c0d..c05eb42deb9a1 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -188,6 +188,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index 5771e2ba0761c..09252b7b7d2db 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -189,6 +189,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index 5771e2ba0761c..09252b7b7d2db 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -189,6 +189,9 @@ condition_variable type_traits
 condition_variable typeinfo
 condition_variable version
 coroutine compare
+coroutine cstddef
+coroutine cstdint
+coroutine cstring
 coroutine iosfwd
 coroutine limits
 coroutine type_traits
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index 406665a213536..ce4ccc3d11615 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -111,19 +111,26 @@ charconv limits
 charconv new
 charconv type_traits
 charconv version
+chrono array
 chrono bit
+chrono cctype
+chrono cerrno
 chrono charconv
+chrono clocale
 chrono cmath
 chrono compare
 chrono concepts
 chrono cstddef
 chrono cstdint
+chrono cstdlib
 chrono cstring
 chrono ctime
-chrono format
+chrono cwchar
 chrono forward_list
 chrono limits
 chrono locale
+chrono new
+chrono optional
 chrono ostream
 chrono ratio
 chrono sstream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index 05c7a6ea18d79..62d931c0eebad 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -67,20 +67,30 @@ charconv initializer_list
 charconv limits
 charconv new
 charconv version
+chrono array
+chrono cctype
+chrono cerrno
+chrono clocale
 chrono cmath
 chrono compare
 chrono cstddef
 chrono cstdint
+chrono cstdlib
+chrono cstring
 chrono ctime
-chrono format
+chrono cwchar
 chrono forward_list
 chrono limits
+chrono new
+chrono optional
 chrono ostream
 chrono ratio
 chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
+chrono tuple
+chrono typeinfo
 chrono vector
 chrono version
 cinttypes cstdint
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index 05c7a6ea18d79..f68249aeec78c 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -67,20 +67,30 @@ charconv initializer_list
 charconv limits
 charconv new
 charconv version
+chrono array
+chrono cctype
+chrono cerrno
+chrono clocale
 chrono cmath
 chrono compare
 chrono cstddef
 chrono cstdint
+chrono cstdlib
+chrono cstring
 chrono ctime
-chrono format
+chrono cwchar
 chrono forward_list
 chrono limits
+chrono new
+chrono optional
 chrono ostream
 chrono ratio
 chrono sstream
 chrono stdexcept
 chrono string
 chrono string_view
+chrono tuple
+chrono typeinfo
 chrono vector
 chrono version
 cinttypes cstdint
@@ -166,6 +176,29 @@ experimental/simd limits
 experimental/type_traits initializer_list
 experimental/type_traits type_traits
 experimental/utility utility
+experimental/vector experimental/memory_resource
+experimental/vector vector
+ext/hash_map algorithm
+ext/hash_map cmath
+ext/hash_map cstddef
+ext/hash_map cstdint
+ext/hash_map cstring
+ext/hash_map functional
+ext/hash_map initializer_list
+ext/hash_map limits
+ext/hash_map new
+ext/hash_map stdexcept
+ext/hash_map string
+ext/hash_set algorithm
+ext/hash_set cmath
+ext/hash_set cstddef
+ext/hash_set cstdint
+ext/hash_set cstring
+ext/hash_set functional
+ext/hash_set initializer_list
+ext/hash_set limits
+ext/hash_set new
+ext/hash_set string
 filesystem compare
 filesystem cstddef
 filesystem cstdint
diff --git a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/ctor.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/ctor.pass.cpp
deleted file mode 100644
index a0b141631f831..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/ctor.pass.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-//  class ambiguous_local_time
-//
-//  template<class Duration>
-//    ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
-
-#include <chrono>
-#include <string_view>
-
-#include "assert_macros.h"
-#include "concat_macros.h"
-
-template <class Duration>
-static void
-test(const std::chrono::local_time<Duration>& tp, const std::chrono::local_info& i, std::string_view expected) {
-  std::chrono::ambiguous_local_time exception{tp, i};
-  std::string_view result = exception.what();
-  TEST_REQUIRE(result == expected,
-               TEST_WRITE_CONCATENATED("Expected output\n", expected, "\n\nActual output\n", result, '\n'));
-}
-
-// The constructor constructs the runtime_error base class with a specific
-// message. This implicitly tests what() too, since that is inherited from
-// runtime_error there is no separate test for what().
-int main(int, char**) {
-  using namespace std::literals::chrono_literals;
-
-  // There is no requirement on the ordering of PREV and NEXT so an "invalid"
-  // overlap is allowed. All tests with negative dates use the same order as
-  // positive tests.
-
-  test(std::chrono::local_time<std::chrono::nanoseconds>{-1ns},
-       std::chrono::local_info{
-           std::chrono::local_info::ambiguous,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "PREV"},
-
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "NEXT"}
-
-       },
-       R"(1969-12-31 23:59:59.999999999 is ambiguous.  It could be
-1969-12-31 23:59:59.999999999 PREV == 1969-12-31 22:59:59.999999999 UTC or
-1969-12-31 23:59:59.999999999 NEXT == 1969-12-31 23:59:59.999999999 UTC)");
-
-  test(std::chrono::local_time<std::chrono::microseconds>{0us},
-       std::chrono::local_info{
-           std::chrono::local_info::ambiguous,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "PREV"},
-
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "NEXT"}},
-       R"(1970-01-01 00:00:00.000000 is ambiguous.  It could be
-1970-01-01 00:00:00.000000 PREV == 1969-12-31 23:00:00.000000 UTC or
-1970-01-01 00:00:00.000000 NEXT == 1970-01-01 00:00:00.000000 UTC)");
-
-  test(std::chrono::local_time<std::chrono::milliseconds>{1ms},
-       std::chrono::local_info{
-           std::chrono::local_info::ambiguous,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "PREV"},
-
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "NEXT"}},
-       R"(1970-01-01 00:00:00.001 is ambiguous.  It could be
-1970-01-01 00:00:00.001 PREV == 1969-12-31 23:00:00.001 UTC or
-1970-01-01 00:00:00.001 NEXT == 1970-01-01 00:00:00.001 UTC)");
-
-  test(std::chrono::local_seconds{(std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},
-       std::chrono::local_info{
-           std::chrono::local_info::ambiguous,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / -21969},
-               std::chrono::sys_days{std::chrono::December / 31 / -21969},
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / -21970},
-               std::chrono::sys_days{std::chrono::March / 1 / -21970} + 23h,
-               1h,
-               60min,
-               "NEXT"}},
-       R"(-21970-01-01 00:00:00 is ambiguous.  It could be
--21970-01-01 00:00:00 PREV == -21970-01-01 00:00:00 UTC or
--21970-01-01 00:00:00 NEXT == -21971-12-31 23:00:00 UTC)");
-
-  test(
-      std::chrono::local_time<std::chrono::days>{
-          (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},
-      std::chrono::local_info{
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info{
-              std::chrono::sys_days{std::chrono::September / 1 / 21969},
-              std::chrono::sys_days{std::chrono::December / 31 / 21969},
-              0s,
-              0min,
-              "PREV"},
-          std::chrono::sys_info{
-              std::chrono::sys_days{std::chrono::January / 1 / 21970},
-              std::chrono::sys_days{std::chrono::March / 1 / 21970} + 23h,
-              1h,
-              60min,
-              "NEXT"}},
-      R"(21970-01-01 is ambiguous.  It could be
-21970-01-01 PREV == 21970-01-01 00:00:00 UTC or
-21970-01-01 NEXT == 21969-12-31 23:00:00 UTC)");
-
-  test(std::chrono::local_time<std::chrono::weeks>{},
-       std::chrono::local_info{
-           std::chrono::local_info::ambiguous,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969},
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970} + 23h,
-               1h,
-               60min,
-               "NEXT"}},
-       R"(1970-01-01 is ambiguous.  It could be
-1970-01-01 PREV == 1970-01-01 00:00:00 UTC or
-1970-01-01 NEXT == 1969-12-31 23:00:00 UTC)");
-
-  // Note months and years can not be streamed.
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/types.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/types.pass.cpp
deleted file mode 100644
index be54aedbbba61..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.ambig/types.pass.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-// ADDITIONAL_COMPILE_FLAGS(clang): -Wno-deprecated
-// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-deprecated-copy-dtor
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class ambiguous_local_time : public runtime_error {
-// public:
-//   template<class Duration>
-//     ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
-// };
-
-#include <chrono>
-#include <stdexcept>
-#include <type_traits>
-
-// Basic properties
-static_assert(std::is_base_of_v<std::runtime_error, std::chrono::ambiguous_local_time>);
-static_assert(!std::is_default_constructible_v<std::chrono::ambiguous_local_time>);
-static_assert(std::is_destructible_v<std::chrono::ambiguous_local_time>);
-static_assert(std::is_copy_constructible_v<std::chrono::ambiguous_local_time>);
-static_assert(std::is_move_constructible_v<std::chrono::ambiguous_local_time>);
-static_assert(std::is_copy_assignable_v<std::chrono::ambiguous_local_time>);
-static_assert(std::is_move_assignable_v<std::chrono::ambiguous_local_time>);
-
-int main(int, char**) {
-  std::chrono::ambiguous_local_time e{
-      std::chrono::local_seconds{}, std::chrono::local_info{std::chrono::local_info::ambiguous, {}, {}}};
-
-  std::chrono::ambiguous_local_time copy = e;
-  copy                                   = e;
-
-  std::chrono::ambiguous_local_time move = std::move(e);
-  e                                      = move;
-  move                                   = std::move(e);
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/ctor.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/ctor.pass.cpp
deleted file mode 100644
index ca03d832a7a9f..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/ctor.pass.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class nonexistent_local_time
-//
-// template<class Duration>
-// nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
-
-#include <chrono>
-#include <string_view>
-
-#include "assert_macros.h"
-#include "concat_macros.h"
-
-template <class Duration>
-static void
-test(const std::chrono::local_time<Duration>& tp, const std::chrono::local_info& i, std::string_view expected) {
-  std::chrono::nonexistent_local_time exception{tp, i};
-  std::string_view result = exception.what();
-  TEST_REQUIRE(result == expected,
-               TEST_WRITE_CONCATENATED("Expected output\n", expected, "\n\nActual output\n", result, '\n'));
-}
-
-// The constructor constructs the runtime_error base class with a specific
-// message. This implicitly tests what() too, since that is inherited from
-// runtime_error there is no separate test for what().
-int main(int, char**) {
-  using namespace std::literals::chrono_literals;
-
-  // There is no requirement on the ordering of PREV and NEXT so an "invalid"
-  // gap is allowed. All tests with negative dates use the same order as
-  // positive tests.
-
-  test(std::chrono::local_time<std::chrono::nanoseconds>{-1ns},
-       std::chrono::local_info{
-           std::chrono::local_info::nonexistent,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "NEXT"}},
-       R"(1969-12-31 23:59:59.999999999 is in a gap between
-1969-12-31 23:00:00 PREV and
-1970-01-01 01:00:00 NEXT which are both equivalent to
-1969-12-31 23:00:00 UTC)");
-
-  test(std::chrono::local_time<std::chrono::microseconds>{0us},
-       std::chrono::local_info{
-           std::chrono::local_info::nonexistent,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "NEXT"}},
-       R"(1970-01-01 00:00:00.000000 is in a gap between
-1969-12-31 23:00:00 PREV and
-1970-01-01 01:00:00 NEXT which are both equivalent to
-1969-12-31 23:00:00 UTC)");
-
-  test(std::chrono::local_time<std::chrono::milliseconds>{1ms},
-       std::chrono::local_info{
-           std::chrono::local_info::nonexistent,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "NEXT"}},
-       R"(1970-01-01 00:00:00.001 is in a gap between
-1969-12-31 23:00:00 PREV and
-1970-01-01 01:00:00 NEXT which are both equivalent to
-1969-12-31 23:00:00 UTC)");
-
-  test(std::chrono::local_seconds{(std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},
-       std::chrono::local_info{
-           std::chrono::local_info::nonexistent,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / -21969},
-               std::chrono::sys_days{std::chrono::December / 31 / -21969} + 23h,
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / -21970},
-               std::chrono::sys_days{std::chrono::March / 1 / -21970},
-               1h,
-               60min,
-               "NEXT"}},
-       R"(-21970-01-01 00:00:00 is in a gap between
--21969-12-31 23:00:00 PREV and
--21970-01-01 01:00:00 NEXT which are both equivalent to
--21969-12-31 23:00:00 UTC)");
-
-  test(
-      std::chrono::local_time<std::chrono::days>{
-          (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},
-      std::chrono::local_info{
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info{
-              std::chrono::sys_days{std::chrono::September / 1 / 21969},
-              std::chrono::sys_days{std::chrono::December / 31 / 21969} + 23h,
-              0s,
-              0min,
-              "PREV"},
-          std::chrono::sys_info{
-              std::chrono::sys_days{std::chrono::January / 1 / 21970},
-              std::chrono::sys_days{std::chrono::March / 1 / 21970},
-              1h,
-              60min,
-              "NEXT"}},
-      R"(21970-01-01 is in a gap between
-21969-12-31 23:00:00 PREV and
-21970-01-01 01:00:00 NEXT which are both equivalent to
-21969-12-31 23:00:00 UTC)");
-
-  test(std::chrono::local_time<std::chrono::weeks>{},
-       std::chrono::local_info{
-           std::chrono::local_info::nonexistent,
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::September / 1 / 1969},
-               std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
-               0s,
-               0min,
-               "PREV"},
-           std::chrono::sys_info{
-               std::chrono::sys_days{std::chrono::January / 1 / 1970},
-               std::chrono::sys_days{std::chrono::March / 1 / 1970},
-               1h,
-               60min,
-               "NEXT"}},
-       R"(1970-01-01 is in a gap between
-1969-12-31 23:00:00 PREV and
-1970-01-01 01:00:00 NEXT which are both equivalent to
-1969-12-31 23:00:00 UTC)");
-
-  // Note months and years can not be streamed.
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/types.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/types.pass.cpp
deleted file mode 100644
index 85ebfab679e02..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/types.pass.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-// ADDITIONAL_COMPILE_FLAGS(clang): -Wno-deprecated
-// ADDITIONAL_COMPILE_FLAGS(gcc): -Wno-deprecated-copy-dtor
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class nonexistent_local_time : public runtime_error {
-// public:
-//   template<class Duration>
-//     nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
-// };
-
-#include <chrono>
-#include <stdexcept>
-#include <type_traits>
-
-// Basic properties
-static_assert(std::is_base_of_v<std::runtime_error, std::chrono::nonexistent_local_time>);
-static_assert(!std::is_default_constructible_v<std::chrono::nonexistent_local_time>);
-static_assert(std::is_destructible_v<std::chrono::nonexistent_local_time>);
-static_assert(std::is_copy_constructible_v<std::chrono::nonexistent_local_time>);
-static_assert(std::is_move_constructible_v<std::chrono::nonexistent_local_time>);
-static_assert(std::is_copy_assignable_v<std::chrono::nonexistent_local_time>);
-static_assert(std::is_move_assignable_v<std::chrono::nonexistent_local_time>);
-
-int main(int, char**) {
-  std::chrono::nonexistent_local_time e{
-      std::chrono::local_seconds{}, std::chrono::local_info{std::chrono::local_info::nonexistent, {}, {}}};
-
-  std::chrono::nonexistent_local_time copy = e;
-  copy                                     = e;
-
-  std::chrono::nonexistent_local_time move = std::move(e);
-  e                                        = move;
-  move                                     = std::move(e);
-
-  return 0;
-}
diff --git a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys.pass.cpp
deleted file mode 100644
index 874c3d52e460b..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/to_sys.pass.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class time_zone;
-
-// template <class _Duration>
-// sys_time<common_type_t<Duration, seconds>>
-//   to_sys(const local_time<Duration>& tp) const;
-
-#include <chrono>
-#include <format>
-#include <cassert>
-#include <string_view>
-
-#include "test_macros.h"
-#include "assert_macros.h"
-#include "concat_macros.h"
-
-// Tests unique conversions. To make sure the test is does not depend on changes
-// in the database it uses a time zone with a fixed offset.
-static void test_unique() {
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::nanoseconds>{-1ns}) ==
-         std::chrono::sys_time<std::chrono::nanoseconds>{-1ns + 1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::microseconds>{0us}) ==
-         std::chrono::sys_time<std::chrono::microseconds>{1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()}) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch() + 1h});
-
-  // sys_time<common_type_t<Duration, seconds>> is seconds for the larger types
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::days>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()}) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch() + 1h});
-
-  assert(tz->to_sys(std::chrono::local_time<std::chrono::weeks>{}) ==
-         std::chrono::sys_time<std::chrono::seconds>{
-             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});
-
-  // Note months and years can not be streamed; thus the function cannot be
-  // instantiated for these types. (Even when there is no exception thrown.)
-}
-
-// Tests non-existant conversions.
-static void test_nonexistent() {
-#ifndef TEST_HAS_NO_EXCEPTIONS
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");
-
-  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap
-  // ...
-  // 1 DE CE%sT 1980
-  // 1 E CE%sT
-  //
-  // ...
-  // R E 1981 ma - Mar lastSu 1u 1 S
-  // R E 1996 ma - O lastSu 1u 0 -
-
-  // Pick an historic date where it's well known what the time zone rules were.
-  // This makes it unlikely updates to the database change these rules.
-  std::chrono::local_time<std::chrono::seconds> time{
-      (std::chrono::sys_days{std::chrono::March / 30 / 1986} + 2h + 30min).time_since_epoch()};
-
-  // Validates whether the database did not change.
-  std::chrono::local_info info = tz->get_info(time);
-  assert(info.result == std::chrono::local_info::nonexistent);
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::nonexistent_local_time,
-      [&]([[maybe_unused]] const std::chrono::nonexistent_local_time& e) {
-        std::string_view what =
-            R"(1986-03-30 02:30:00.000000000 is in a gap between
-1986-03-30 02:00:00 CET and
-1986-03-30 03:00:00 CEST which are both equivalent to
-1986-03-30 01:00:00 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0ns));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::nonexistent_local_time,
-      [&]([[maybe_unused]] const std::chrono::nonexistent_local_time& e) {
-        std::string_view what =
-            R"(1986-03-30 02:30:00.000000 is in a gap between
-1986-03-30 02:00:00 CET and
-1986-03-30 03:00:00 CEST which are both equivalent to
-1986-03-30 01:00:00 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0us));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::nonexistent_local_time,
-      [&]([[maybe_unused]] const std::chrono::nonexistent_local_time& e) {
-        std::string_view what =
-            R"(1986-03-30 02:30:00.000 is in a gap between
-1986-03-30 02:00:00 CET and
-1986-03-30 03:00:00 CEST which are both equivalent to
-1986-03-30 01:00:00 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0ms));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::nonexistent_local_time,
-      [&]([[maybe_unused]] const std::chrono::nonexistent_local_time& e) {
-        std::string_view what =
-            R"(1986-03-30 02:30:00 is in a gap between
-1986-03-30 02:00:00 CET and
-1986-03-30 03:00:00 CEST which are both equivalent to
-1986-03-30 01:00:00 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0s));
-
-#endif // TEST_HAS_NO_EXCEPTIONS
-}
-
-// Tests ambiguous conversions.
-static void test_ambiguous() {
-#ifndef TEST_HAS_NO_EXCEPTIONS
-  using namespace std::literals::chrono_literals;
-
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");
-
-  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap
-  // ...
-  // 1 DE CE%sT 1980
-  // 1 E CE%sT
-  //
-  // ...
-  // R E 1981 ma - Mar lastSu 1u 1 S
-  // R E 1996 ma - O lastSu 1u 0 -
-
-  // Pick an historic date where it's well known what the time zone rules were.
-  // This makes it unlikely updates to the database change these rules.
-  std::chrono::local_time<std::chrono::seconds> time{
-      (std::chrono::sys_days{std::chrono::September / 28 / 1986} + 2h + 30min).time_since_epoch()};
-
-  // Validates whether the database did not change.
-  std::chrono::local_info info = tz->get_info(time);
-  assert(info.result == std::chrono::local_info::ambiguous);
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::ambiguous_local_time,
-      [&]([[maybe_unused]] const std::chrono::ambiguous_local_time& e) {
-        std::string_view what =
-            R"(1986-09-28 02:30:00.000000000 is ambiguous.  It could be
-1986-09-28 02:30:00.000000000 CEST == 1986-09-28 00:30:00.000000000 UTC or
-1986-09-28 02:30:00.000000000 CET == 1986-09-28 01:30:00.000000000 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0ns));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::ambiguous_local_time,
-      [&]([[maybe_unused]] const std::chrono::ambiguous_local_time& e) {
-        std::string_view what =
-            R"(1986-09-28 02:30:00.000000 is ambiguous.  It could be
-1986-09-28 02:30:00.000000 CEST == 1986-09-28 00:30:00.000000 UTC or
-1986-09-28 02:30:00.000000 CET == 1986-09-28 01:30:00.000000 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0us));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::ambiguous_local_time,
-      [&]([[maybe_unused]] const std::chrono::ambiguous_local_time& e) {
-        std::string_view what =
-            R"(1986-09-28 02:30:00.000 is ambiguous.  It could be
-1986-09-28 02:30:00.000 CEST == 1986-09-28 00:30:00.000 UTC or
-1986-09-28 02:30:00.000 CET == 1986-09-28 01:30:00.000 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0ms));
-
-  TEST_VALIDATE_EXCEPTION(
-      std::chrono::ambiguous_local_time,
-      [&]([[maybe_unused]] const std::chrono::ambiguous_local_time& e) {
-        std::string_view what =
-            R"(1986-09-28 02:30:00 is ambiguous.  It could be
-1986-09-28 02:30:00 CEST == 1986-09-28 00:30:00 UTC or
-1986-09-28 02:30:00 CET == 1986-09-28 01:30:00 UTC)";
-        TEST_LIBCPP_REQUIRE(
-            e.what() == what,
-            TEST_WRITE_CONCATENATED("Expected exception\n", what, "\n\nActual exception\n", e.what(), '\n'));
-      },
-      tz->to_sys(time + 0s));
-
-#endif // TEST_HAS_NO_EXCEPTIONS
-}
-
-// This test does the basic validations of this function. The library function
-// uses `local_info get_info(const local_time<Duration>& tp)` as implementation
-// detail. The get_info function does extensive testing of the data.
-int main(int, char**) {
-  test_unique();
-  test_nonexistent();
-  test_ambiguous();
-
-  return 0;
-}

>From e07e5c324cbd8ac5bca4c7e1d9c7a20da980d513 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:06:45 -0700
Subject: [PATCH 5/6] Revert "[HWASan] skip libcxx test that times out with
 hwasan"

This reverts commit 503fb1aaf4b322173721fbf3855f2168cf6b230b.
---
 .../time.zone.members/get_info.local_time.pass.cpp              | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp
index a8c468a6c6fd4..6dc15974c4484 100644
--- a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp
+++ b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp
@@ -11,8 +11,6 @@
 
 // XFAIL: libcpp-has-no-experimental-tzdb
 // XFAIL: availability-tzdb-missing
-// Times out under HWASan
-// XFAIL: hwasan
 
 // <chrono>
 

>From 9f2909bdcf6c90d603b776c493f27acad18145de Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Mon, 10 Jun 2024 16:06:53 -0700
Subject: [PATCH 6/6] Revert "[libc++][TZDB] Implements time_zone
 get_info(local_time). (#89537)"

This reverts commit de736d9c6a7634285c4283b369a9442a9d191cd9.
---
 libcxx/include/__chrono/time_zone.h           |    8 -
 libcxx/include/chrono                         |    3 -
 libcxx/src/time_zone.cpp                      |  147 --
 .../diagnostics/chrono.nodiscard.verify.cpp   |    2 -
 .../get_info.local_time.pass.cpp              | 1302 -----------------
 5 files changed, 1462 deletions(-)
 delete mode 100644 libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp

diff --git a/libcxx/include/__chrono/time_zone.h b/libcxx/include/__chrono/time_zone.h
index e28c9189c381b..91ddab8903fe2 100644
--- a/libcxx/include/__chrono/time_zone.h
+++ b/libcxx/include/__chrono/time_zone.h
@@ -16,9 +16,7 @@
 // Enable the contents of the header only when libc++ was built with experimental features enabled.
 #if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB)
 
-#  include <__chrono/calendar.h>
 #  include <__chrono/duration.h>
-#  include <__chrono/local_info.h>
 #  include <__chrono/sys_info.h>
 #  include <__chrono/system_clock.h>
 #  include <__compare/strong_order.h>
@@ -65,18 +63,12 @@ class _LIBCPP_AVAILABILITY_TZDB time_zone {
     return __get_info(chrono::time_point_cast<seconds>(__time));
   }
 
-  template <class _Duration>
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_info get_info(const local_time<_Duration>& __time) const {
-    return __get_info(chrono::time_point_cast<seconds>(__time));
-  }
-
   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; }
 
 private:
   [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept;
 
   [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const;
-  [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info __get_info(local_seconds __time) const;
 
   unique_ptr<__impl> __impl_;
 };
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 4d8398af1a108..96a3e92faa81f 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -763,9 +763,6 @@ class time_zone {
 
   template<class Duration>
   sys_info get_info(const sys_time<Duration>& st) const;
-
-  template<class Duration>
-  local_info get_info(const local_time<Duration>& tp) const;
 };
 bool operator==(const time_zone& x, const time_zone& y) noexcept;                // C++20
 strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;    // C++20
diff --git a/libcxx/src/time_zone.cpp b/libcxx/src/time_zone.cpp
index 764a89ab513c8..928f3d2855e45 100644
--- a/libcxx/src/time_zone.cpp
+++ b/libcxx/src/time_zone.cpp
@@ -34,7 +34,6 @@
 #include <chrono>
 #include <expected>
 #include <map>
-#include <numeric>
 #include <ranges>
 
 #include "include/tzdb/time_zone_private.h"
@@ -904,152 +903,6 @@ time_zone::__get_info(sys_seconds __time) const {
   std::__throw_runtime_error("tzdb: corrupt db");
 }
 
-// Is the "__local_time" present in "__first" and "__second". If so the
-// local_info has an ambiguous result.
-[[nodiscard]] static bool
-__is_ambiguous(local_seconds __local_time, const sys_info& __first, const sys_info& __second) {
-  std::chrono::local_seconds __end_first{__first.end.time_since_epoch() + __first.offset};
-  std::chrono::local_seconds __begin_second{__second.begin.time_since_epoch() + __second.offset};
-
-  return __local_time < __end_first && __local_time >= __begin_second;
-}
-
-// Determines the result of the "__local_time". This expects the object
-// "__first" to be earlier in time than "__second".
-[[nodiscard]] static local_info
-__get_info(local_seconds __local_time, const sys_info& __first, const sys_info& __second) {
-  std::chrono::local_seconds __end_first{__first.end.time_since_epoch() + __first.offset};
-  std::chrono::local_seconds __begin_second{__second.begin.time_since_epoch() + __second.offset};
-
-  if (__local_time < __end_first) {
-    if (__local_time >= __begin_second)
-      // |--------|
-      //        |------|
-      //         ^
-      return {local_info::ambiguous, __first, __second};
-
-    // |--------|
-    //          |------|
-    //         ^
-    return {local_info::unique, __first, sys_info{}};
-  }
-
-  if (__local_time < __begin_second)
-    // |--------|
-    //             |------|
-    //           ^
-    return {local_info::nonexistent, __first, __second};
-
-  // |--------|
-  //          |------|
-  //           ^
-  return {local_info::unique, __second, sys_info{}};
-}
-
-[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info
-time_zone::__get_info(local_seconds __local_time) const {
-  seconds __local_seconds = __local_time.time_since_epoch();
-
-  /* An example of a typical year with a DST switch displayed in local time.
-   *
-   * At the first of April the time goes forward one hour. This means the
-   * time marked with ~~ is not a valid local time. This is represented by the
-   * nonexistent value in local_info.result.
-   *
-   * At the first of November the time goes backward one hour. This means the
-   * time marked with ^^ happens twice. This is represented by the ambiguous
-   * value in local_info.result.
-   *
-   * 2020.11.01                  2021.04.01              2021.11.01
-   * offset +05                  offset +05              offset +05
-   * save    0s                  save    1h              save    0s
-   * |------------//----------|
-   *                             |---------//--------------|
-   *                                                    |-------------
-   *                           ~~                        ^^
-   *
-   * These shifts can happen due to changes in the current time zone for a
-   * location. For example, Indian/Kerguelen switched only once. In 1950 from an
-   * offset of 0 hours to an offset of +05 hours.
-   *
-   * During all these shifts the UTC time will not have gaps.
-   */
-
-  // The code needs to determine the system time for the local time. There is no
-  // information available. Assume the offset between system time and local time
-  // is 0s. This gives an initial estimate.
-  sys_seconds __guess{__local_seconds};
-  sys_info __info = __get_info(__guess);
-
-  // At this point the offset can be used to determine an estimate for the local
-  // time. Before doing that, determine the offset and validate whether the
-  // local time is the range [chrono::local_seconds::min(),
-  // chrono::local_seconds::max()).
-  if (__local_seconds < 0s && __info.offset > 0s)
-    if (__local_seconds - chrono::local_seconds::min().time_since_epoch() < __info.offset)
-      return {-1, __info, {}};
-
-  if (__local_seconds > 0s && __info.offset < 0s)
-    if (chrono::local_seconds::max().time_since_epoch() - __local_seconds < -__info.offset)
-      return {-2, __info, {}};
-
-  // Based on the information found in the sys_info, the local time can be
-  // converted to a system time. This resulting time can be in the following
-  // locations of the sys_info:
-  //
-  //                             |---------//--------------|
-  //                           1   2.1      2.2         2.3  3
-  //
-  // 1. The estimate is before the returned sys_info object.
-  //    The result is either non-existent or unique in the previous sys_info.
-  // 2. The estimate is in the sys_info object
-  //    - If the sys_info begin is not sys_seconds::min(), then it might be at
-  //      2.1 and could be ambiguous with the previous or unique.
-  //    - If sys_info end is not sys_seconds::max(), then it might be at 2.3
-  //      and could be ambiguous with the next or unique.
-  //    - Else it is at 2.2 and always unique. This case happens when a
-  //      time zone has no transitions. For example, UTC or GMT+1.
-  // 3. The estimate is after the returned sys_info object.
-  //    The result is either non-existent or unique in the next sys_info.
-  //
-  // There is no specification where the "middle" starts. Similar issues can
-  // happen when sys_info objects are "short", then "unique in the next" could
-  // become "ambiguous in the next and the one following". Theoretically there
-  // is the option of the following time-line
-  //
-  // |------------|
-  //           |----|
-  //       |-----------------|
-  //
-  // However the local_info object only has 2 sys_info objects, so this option
-  // is not tested.
-
-  sys_seconds __sys_time{__local_seconds - __info.offset};
-  if (__sys_time < __info.begin)
-    // Case 1 before __info
-    return chrono::__get_info(__local_time, __get_info(__info.begin - 1s), __info);
-
-  if (__sys_time >= __info.end)
-    // Case 3 after __info
-    return chrono::__get_info(__local_time, __info, __get_info(__info.end));
-
-  // Case 2 in __info
-  if (__info.begin != sys_seconds::min()) {
-    // Case 2.1 Not at the beginning, when not ambiguous the result should test
-    // case 2.3.
-    sys_info __prev = __get_info(__info.begin - 1s);
-    if (__is_ambiguous(__local_time, __prev, __info))
-      return {local_info::ambiguous, __prev, __info};
-  }
-
-  if (__info.end == sys_seconds::max())
-    // At the end so it's case 2.2
-    return {local_info::unique, __info, sys_info{}};
-
-  // This tests case 2.2 or case 2.3.
-  return chrono::__get_info(__local_time, __info, __get_info(__info.end));
-}
-
 } // namespace chrono
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index fea1e4417cc12..a5ce5d1658130 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -48,10 +48,8 @@ void test() {
 
   {
     std::chrono::sys_seconds s{};
-    std::chrono::local_seconds l{};
     tz.name();           // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     tz.get_info(s);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-    tz.get_info(l);      // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     operator==(tz, tz);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
     operator<=>(tz, tz); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
   }
diff --git a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp
deleted file mode 100644
index 6dc15974c4484..0000000000000
--- a/libcxx/test/std/time/time.zone/time.zone.timezone/time.zone.members/get_info.local_time.pass.cpp
+++ /dev/null
@@ -1,1302 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
-
-// XFAIL: libcpp-has-no-experimental-tzdb
-// XFAIL: availability-tzdb-missing
-
-// <chrono>
-
-// class time_zone;
-
-// template <class _Duration>
-//   local_info get_info(const local_time<_Duration>& time) const;
-
-// This test uses the system provided database. This makes the test portable,
-// but may cause failures when the database information changes. Historic data
-// may change if new facts are uncovered, future data may change when regions
-// change their time zone or daylight saving time. Most tests will not look in
-// the future to attempt to avoid issues. All tests list the data on which they
-// are based, this makes debugging easier upon failure; including to see whether
-// the provided data has not been changed.
-//
-// The first part of the test is manually crafted, the second part compares the
-// transitions for all time zones in the database.
-
-#include <algorithm>
-#include <cassert>
-#include <chrono>
-#include <format>
-
-#include "test_macros.h"
-#include "assert_macros.h"
-#include "concat_macros.h"
-
-// The year range to validate. The dates used in practice are expected to be
-// inside the tested range.
-constexpr std::chrono::year first{1800};
-constexpr std::chrono::year last{2100};
-
-/***** ***** HELPERS ***** *****/
-
-[[nodiscard]] static std::chrono::sys_seconds to_sys_seconds(
-    std::chrono::year year,
-    std::chrono::month month,
-    std::chrono::day day,
-    std::chrono::hours h   = std::chrono::hours(0),
-    std::chrono::minutes m = std::chrono::minutes{0},
-    std::chrono::seconds s = std::chrono::seconds{0}) {
-  std::chrono::year_month_day result{year, month, day};
-
-  return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::sys_days>(result)) + h + m + s;
-}
-
-[[nodiscard]] static std::chrono::local_seconds to_local_seconds(
-    std::chrono::year year,
-    std::chrono::month month,
-    std::chrono::day day,
-    std::chrono::hours h   = std::chrono::hours(0),
-    std::chrono::minutes m = std::chrono::minutes{0},
-    std::chrono::seconds s = std::chrono::seconds{0}) {
-  std::chrono::year_month_day result{year, month, day};
-
-  return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::local_days>(result)) + h + m + s;
-}
-
-static void assert_equal(const std::chrono::sys_info& lhs, const std::chrono::sys_info& rhs) {
-  TEST_REQUIRE(lhs.begin == rhs.begin,
-               TEST_WRITE_CONCATENATED("\nBegin:\nExpected output ", lhs.begin, "\nActual output   ", rhs.begin, '\n'));
-  TEST_REQUIRE(lhs.end == rhs.end,
-               TEST_WRITE_CONCATENATED("\nEnd:\nExpected output ", lhs.end, "\nActual output   ", rhs.end, '\n'));
-  TEST_REQUIRE(
-      lhs.offset == rhs.offset,
-      TEST_WRITE_CONCATENATED("\nOffset:\nExpected output ", lhs.offset, "\nActual output   ", rhs.offset, '\n'));
-  TEST_REQUIRE(lhs.save == rhs.save,
-               TEST_WRITE_CONCATENATED("\nSave:\nExpected output ", lhs.save, "\nActual output   ", rhs.save, '\n'));
-  TEST_REQUIRE(
-      lhs.abbrev == rhs.abbrev,
-      TEST_WRITE_CONCATENATED("\nAbbrev:\nExpected output ", lhs.abbrev, "\nActual output   ", rhs.abbrev, '\n'));
-}
-
-static void assert_equal(const std::chrono::local_info& lhs, const std::chrono::local_info& rhs) {
-  TEST_REQUIRE(
-      lhs.result == rhs.result,
-      TEST_WRITE_CONCATENATED("\nResult:\nExpected output ", lhs.result, "\nActual output   ", rhs.result, '\n'));
-
-  assert_equal(lhs.first, rhs.first);
-  assert_equal(lhs.second, rhs.second);
-}
-
-/***** ***** TESTS ***** *****/
-
-static void test_gmt() {
-  // Simple zone always valid, no rule entries, lookup using a link.
-  // L Etc/GMT GMT
-  // Z Etc/GMT 0 - GMT
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("GMT");
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 0s, 0min, "GMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-}
-
-static void test_local_time_out_of_range() {
-  // Fixed positive offset
-  // Etc/GMT-1 1 - +01
-
-  using namespace std::literals::chrono_literals;
-  { // lower bound
-    const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT-1");
-
-    assert_equal(
-        std::chrono::local_info(
-            -1,
-            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),
-            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-        tz->get_info(std::chrono::local_seconds::min()));
-
-    assert_equal(
-        std::chrono::local_info(
-            -1,
-            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),
-            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-        tz->get_info(std::chrono::local_seconds::min() + 59min + 59s));
-
-    assert_equal(
-        std::chrono::local_info(
-            std::chrono::local_info::unique,
-            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),
-            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-        tz->get_info(std::chrono::local_seconds::min() + 1h));
-  }
-
-  { // upper bound
-    const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");
-
-    assert_equal(
-        std::chrono::local_info(
-            -2,
-            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), -1h, 0min, "-01"),
-            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-        tz->get_info(std::chrono::local_seconds::max() - 1s));
-
-    assert_equal(
-        std::chrono::local_info(
-            std::chrono::local_info::unique,
-            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), -1h, 0min, "-01"),
-            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-        tz->get_info(std::chrono::local_seconds::max() - 1h - 1s));
-  }
-}
-
-static void test_indian_kerguelen() {
-  // One change, no rules, no dst changes.
-
-  // Z Indian/Kerguelen 0 - -00 1950
-  // 5 - +05
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Indian/Kerguelen");
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1950y, std::chrono::January, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1950y, std::chrono::January, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(
-              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05")),
-      tz->get_info(to_local_seconds(1950y, std::chrono::January, 1d)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1950y, std::chrono::January, 1d, 5h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::max() - 1s));
-}
-
-static void test_antarctica_rothera() {
-  // One change, no rules, no dst changes
-
-  // Z Antarctica/Rothera 0 - -00 1976 D
-  // -3 - -03
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Antarctica/Rothera");
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 20h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(
-              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03")),
-      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 21h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),
-          std::chrono::sys_info(
-              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03")),
-      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 23h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1976y, std::chrono::December, 1d)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::max() - 3h - 1s));
-
-  assert_equal(
-      std::chrono::local_info(
-          -2,
-          std::chrono::sys_info(
-              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::max() - 1s));
-}
-
-static void test_asia_hong_kong() {
-  // A more typical entry, first some hard-coded entires and then at the
-  // end a rules based entry. This rule is valid for its entire period
-  //
-  // Z Asia/Hong_Kong 7:36:42 - LMT 1904 O 30 0:36:42
-  // 8 - HKT 1941 Jun 15 3
-  // 8 1 HKST 1941 O 1 4
-  // 8 0:30 HKWT 1941 D 25
-  // 9 - JST 1945 N 18 2
-  // 8 HK HK%sT
-  //
-  // R HK 1946 o - Ap 21 0 1 S
-  // R HK 1946 o - D 1 3:30s 0 -
-  // R HK 1947 o - Ap 13 3:30s 1 S
-  // R HK 1947 o - N 30 3:30s 0 -
-  // R HK 1948 o - May 2 3:30s 1 S
-  // R HK 1948 1952 - O Su>=28 3:30s 0 -
-  // R HK 1949 1953 - Ap Su>=1 3:30 1 S
-  // R HK 1953 1964 - O Su>=31 3:30 0 -
-  // R HK 1954 1964 - Mar Su>=18 3:30 1 S
-  // R HK 1965 1976 - Ap Su>=16 3:30 1 S
-  // R HK 1965 1976 - O Su>=16 3:30 0 -
-  // R HK 1973 o - D 30 3:30 1 S
-  // R HK 1979 o - May 13 3:30 1 S
-  // R HK 1979 o - O 21 3:30 0 -
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Asia/Hong_Kong");
-
-  assert_equal(
-      std::chrono::local_info(
-          -1,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          -1,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min() + 7h + 36min + 41s));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min() + 7h + 36min + 42s));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 36min, 41s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT")),
-      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 36min, 42s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              7h + 36min + 42s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT")),
-      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 1h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              8h,
-              0min,
-              "HKT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 3h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 4h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 29min, 29s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),
-              8h + 30min,
-              30min,
-              "HKWT")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 30min)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              9h,
-              60min,
-              "HKST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),
-              8h + 30min,
-              30min,
-              "HKWT")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),
-              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),
-              8h + 30min,
-              30min,
-              "HKWT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 4h)));
-}
-
-static void test_europe_berlin() {
-  // A more typical entry, first some hard-coded entires and then at the
-  // end a rules based entry. This rule is valid for its entire period
-  //
-
-  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap
-  // 1 c CE%sT 1945 May 24 2
-  // 1 So CE%sT 1946
-  // 1 DE CE%sT 1980
-  // 1 E CE%sT
-  //
-  // R c 1916 o - Ap 30 23 1 S
-  // R c 1916 o - O 1 1 0 -
-  // R c 1917 1918 - Ap M>=15 2s 1 S
-  // R c 1917 1918 - S M>=15 2s 0 -
-  // R c 1940 o - Ap 1 2s 1 S
-  // R c 1942 o - N 2 2s 0 -
-  // R c 1943 o - Mar 29 2s 1 S
-  // R c 1943 o - O 4 2s 0 -
-  // R c 1944 1945 - Ap M>=1 2s 1 S
-  // R c 1944 o - O 2 2s 0 -
-  // R c 1945 o - S 16 2s 0 -
-  // R c 1977 1980 - Ap Su>=1 2s 1 S
-  // R c 1977 o - S lastSu 2s 0 -
-  // R c 1978 o - O 1 2s 0 -
-  // R c 1979 1995 - S lastSu 2s 0 -
-  // R c 1981 ma - Mar lastSu 2s 1 S
-  // R c 1996 ma - O lastSu 2s 0 -
-  //
-  // R So 1945 o - May 24 2 2 M
-  // R So 1945 o - S 24 3 1 S
-  // R So 1945 o - N 18 2s 0 -
-  //
-  // R DE 1946 o - Ap 14 2s 1 S
-  // R DE 1946 o - O 7 2s 0 -
-  // R DE 1947 1949 - O Su>=1 2s 0 -
-  // R DE 1947 o - Ap 6 3s 1 S
-  // R DE 1947 o - May 11 2s 2 M
-  // R DE 1947 o - Jun 29 3 1 S
-  // R DE 1948 o - Ap 18 2s 1 S
-  // R DE 1949 o - Ap 10 2s 1 S
-  //
-  // R E 1977 1980 - Ap Su>=1 1u 1 S
-  // R E 1977 o - S lastSu 1u 0 -
-  // R E 1978 o - O 1 1u 0 -
-  // R E 1979 1995 - S lastSu 1u 0 -
-  // R E 1981 ma - Mar lastSu 1u 1 S
-  // R E 1996 ma - O lastSu 1u 0 -
-  //
-  // Note the European Union decided to stop the seasonal change in
-  // 2021. In 2023 seasonal changes are still in effect.
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");
-
-  assert_equal(
-      std::chrono::local_info(
-          -1,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),
-              53min + 28s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          -1,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),
-              53min + 28s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min() + 53min + 27s));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),
-              53min + 28s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min() + 53min + 28s));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),
-              53min + 28s,
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1893y, std::chrono::March, 31d, 23h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              1h,
-              0min,
-              "CET"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              1h,
-              0min,
-              "CET"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              1h,
-              0min,
-              "CET"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 3h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 4h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 3h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 4h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 1h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 2h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              3h,
-              120min,
-              "CEMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 1h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),
-              1h,
-              0min,
-              "CET")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 2h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::June, 29d),
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              2h,
-              60min,
-              "CEST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),
-              1h,
-              0min,
-              "CET")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),
-              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),
-              1h,
-              0min,
-              "CET"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 3h)));
-}
-
-static void test_europe_dublin() {
-  // Z Europe/Dublin -0:25:21 - LMT 1880 Au 2
-  // -0:25:21 - DMT 1916 May 21 2s
-  // -0:25:21 1 IST 1916 O 1 2s
-  // 0 G %s 1921 D 6
-  // ...
-  //
-  // R G 1916 o - May 21 2s 1 BST
-  // R G 1916 o - O 1 2s 0 GMT
-  // R G 1917 o - Ap 8 2s 1 BST
-  // ...
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Dublin");
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1880y, std::chrono::August, 1d, 23h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "DMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1880y, std::chrono::August, 2d)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "DMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 1h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "DMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              34min + 39s,
-              60min,
-              "IST")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 2h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              -(25min + 21s),
-              0min,
-              "DMT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              34min + 39s,
-              60min,
-              "IST")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              34min + 39s,
-              60min,
-              "IST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 6h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              34min + 39s,
-              60min,
-              "IST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 2h, 25min, 20s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              34min + 39s,
-              60min,
-              "IST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),
-              0s,
-              0min,
-              "GMT")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),
-              0s,
-              0min,
-              "GMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),
-              0s,
-              0min,
-              "GMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 1h, 59min, 59s)));
-}
-
-static void test_america_st_johns() {
-  // A more typical entry,
-  // Uses letters both when DST is ative and not and has multiple
-  // letters. Uses negetive offsets.
-  // Switches several times between their own and Canadian rules
-  // Switches the stdoff from -3:30:52 to -3:30 while observing the same rule
-
-  // Z America/St_Johns -3:30:52 - LMT 1884
-  // -3:30:52 j N%sT 1918
-  // -3:30:52 C N%sT 1919
-  // ...
-  //
-  // R j 1917 o - Ap 8 2 1 D
-  // R j 1917 o - S 17 2 0 S
-  // R j 1919 o - May 5 23 1 D
-  // R j 1919 o - Au 12 23 0 S
-  // R j 1920 1935 - May Su>=1 23 1 D
-  // ...
-  //
-  // R C 1918 o - Ap 14 2 1 D
-  // R C 1918 o - O 27 2 0 S
-  // R C 1942 o - F 9 2 1 W
-  // ...
-
-  using namespace std::literals::chrono_literals;
-  const std::chrono::time_zone* tz = std::chrono::locate_zone("America/St_Johns");
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(std::chrono::local_seconds::min()));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              std::chrono::sys_seconds::min(),
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "LMT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1883y, std::chrono::December, 31d, 23h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1884y, std::chrono::January, 1d)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 1h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 2h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::nonexistent,
-          std::chrono::sys_info(
-              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST"),
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 2h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 3h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 0h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 1h)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::ambiguous,
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              -(2h + 30min + 52s),
-              60min,
-              "NDT"),
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 1h, 59min, 59s)));
-
-  assert_equal(
-      std::chrono::local_info(
-          std::chrono::local_info::unique,
-          std::chrono::sys_info(
-              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),
-              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),
-              -(3h + 30min + 52s),
-              0min,
-              "NST"),
-          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 2h)));
-}
-
-static void validate_transitions(const std::chrono::time_zone& zone) {
-  using namespace std::literals::chrono_literals;
-
-  constexpr auto begin = std::chrono::time_point_cast<std::chrono::seconds>(
-      static_cast<std::chrono::sys_days>(std::chrono::year_month_day{first, std::chrono::January, 1d}));
-  constexpr auto end = std::chrono::time_point_cast<std::chrono::seconds>(
-      static_cast<std::chrono::sys_days>(std::chrono::year_month_day{last, std::chrono::January, 1d}));
-
-  // Builds the set of sys_info objects for the selected time range.
-  std::vector<std::chrono::sys_info> input;
-  std::chrono::sys_seconds s = begin;
-  do {
-    input.emplace_back(zone.get_info(s));
-    s = input.back().end;
-  } while (s < end);
-
-  for (auto previous = input.begin(), next = previous + 1; next != input.end(); ++previous, ++next) {
-    // Now iterates to all adjacent objects.
-    // For every transition gets the locate time of the
-    // - end of the first          (a)
-    // - the start if the second   (b)
-    // Depending on the difference between 'a' and 'b' different tests are done.
-    std::chrono::local_seconds end_previous{previous->end.time_since_epoch() + previous->offset};
-    std::chrono::local_seconds begin_next{next->begin.time_since_epoch() + next->offset};
-
-    if (end_previous == begin_next) {
-      // unique transition
-      // a |------------|
-      // b              |----------|
-      //                T
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *previous,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(end_previous - 1s));
-
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *next,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(begin_next));
-
-    } else if (end_previous < begin_next) {
-      // non-existent transition
-      // a |------------|
-      // b                 |----------|
-      //                T  T
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *previous,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(end_previous - 1s));
-
-      assert_equal(std::chrono::local_info(std::chrono::local_info::nonexistent, *previous, *next),
-                   zone.get_info(end_previous));
-
-      assert_equal(std::chrono::local_info(std::chrono::local_info::nonexistent, *previous, *next),
-                   zone.get_info(begin_next - 1s));
-
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *next,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(begin_next));
-
-    } else {
-      // ambiguous transition
-      // a |------------|
-      // b           |----------|
-      //             T  T
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *previous,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(begin_next - 1s));
-
-      assert_equal(std::chrono::local_info(std::chrono::local_info::ambiguous, *previous, *next),
-                   zone.get_info(begin_next));
-
-      assert_equal(std::chrono::local_info(std::chrono::local_info::ambiguous, *previous, *next),
-                   zone.get_info(end_previous - 1s));
-
-      assert_equal(std::chrono::local_info(
-                       std::chrono::local_info::unique,
-                       *next,
-                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),
-                   zone.get_info(end_previous));
-    }
-  }
-}
-
-int main(int, const char**) {
-  test_gmt();
-  test_local_time_out_of_range();
-  test_indian_kerguelen();
-  test_antarctica_rothera();
-
-  test_asia_hong_kong();
-  test_europe_berlin();
-  test_europe_dublin();
-  test_america_st_johns();
-
-  const std::chrono::tzdb& tzdb = std::chrono::get_tzdb();
-  for (const auto& zone : tzdb.zones) {
-    validate_transitions(zone);
-  }
-
-  return 0;
-}



More information about the libcxx-commits mailing list