brintos

brintos / llvm-project-archived public Read only

0
0
Text · 51.6 KiB · 1d02344 Raw
1307 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: no-filesystem, no-localization, no-tzdb11// REQUIRES: long_tests12 13// XFAIL: libcpp-has-no-experimental-tzdb14// XFAIL: availability-tzdb-missing15 16// TODO TZDB Investigate why this fails.17// UNSUPPORTED: target={{.*}}18 19// <chrono>20 21// class time_zone;22 23// template <class _Duration>24//   local_info get_info(const local_time<_Duration>& time) const;25 26// This test uses the system provided database. This makes the test portable,27// but may cause failures when the database information changes. Historic data28// may change if new facts are uncovered, future data may change when regions29// change their time zone or daylight saving time. Most tests will not look in30// the future to attempt to avoid issues. All tests list the data on which they31// are based, this makes debugging easier upon failure; including to see whether32// the provided data has not been changed.33//34// The first part of the test is manually crafted, the second part compares the35// transitions for all time zones in the database.36 37#include <algorithm>38#include <cassert>39#include <chrono>40#include <format>41 42#include "test_macros.h"43#include "assert_macros.h"44#include "concat_macros.h"45 46// The year range to validate. The dates used in practice are expected to be47// inside the tested range.48constexpr std::chrono::year first{1800};49constexpr std::chrono::year last{2100};50 51/***** ***** HELPERS ***** *****/52 53[[nodiscard]] static std::chrono::sys_seconds to_sys_seconds(54    std::chrono::year year,55    std::chrono::month month,56    std::chrono::day day,57    std::chrono::hours h   = std::chrono::hours(0),58    std::chrono::minutes m = std::chrono::minutes{0},59    std::chrono::seconds s = std::chrono::seconds{0}) {60  std::chrono::year_month_day result{year, month, day};61 62  return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::sys_days>(result)) + h + m + s;63}64 65[[nodiscard]] static std::chrono::local_seconds to_local_seconds(66    std::chrono::year year,67    std::chrono::month month,68    std::chrono::day day,69    std::chrono::hours h   = std::chrono::hours(0),70    std::chrono::minutes m = std::chrono::minutes{0},71    std::chrono::seconds s = std::chrono::seconds{0}) {72  std::chrono::year_month_day result{year, month, day};73 74  return std::chrono::time_point_cast<std::chrono::seconds>(static_cast<std::chrono::local_days>(result)) + h + m + s;75}76 77static void assert_equal(const std::chrono::sys_info& lhs, const std::chrono::sys_info& rhs) {78  TEST_REQUIRE(lhs.begin == rhs.begin,79               TEST_WRITE_CONCATENATED("\nBegin:\nExpected output ", lhs.begin, "\nActual output   ", rhs.begin, '\n'));80  TEST_REQUIRE(lhs.end == rhs.end,81               TEST_WRITE_CONCATENATED("\nEnd:\nExpected output ", lhs.end, "\nActual output   ", rhs.end, '\n'));82  TEST_REQUIRE(83      lhs.offset == rhs.offset,84      TEST_WRITE_CONCATENATED("\nOffset:\nExpected output ", lhs.offset, "\nActual output   ", rhs.offset, '\n'));85  TEST_REQUIRE(lhs.save == rhs.save,86               TEST_WRITE_CONCATENATED("\nSave:\nExpected output ", lhs.save, "\nActual output   ", rhs.save, '\n'));87  TEST_REQUIRE(88      lhs.abbrev == rhs.abbrev,89      TEST_WRITE_CONCATENATED("\nAbbrev:\nExpected output ", lhs.abbrev, "\nActual output   ", rhs.abbrev, '\n'));90}91 92static void assert_equal(const std::chrono::local_info& lhs, const std::chrono::local_info& rhs) {93  TEST_REQUIRE(94      lhs.result == rhs.result,95      TEST_WRITE_CONCATENATED("\nResult:\nExpected output ", lhs.result, "\nActual output   ", rhs.result, '\n'));96 97  assert_equal(lhs.first, rhs.first);98  assert_equal(lhs.second, rhs.second);99}100 101/***** ***** TESTS ***** *****/102 103static void test_gmt() {104  // Simple zone always valid, no rule entries, lookup using a link.105  // L Etc/GMT GMT106  // Z Etc/GMT 0 - GMT107 108  using namespace std::literals::chrono_literals;109  const std::chrono::time_zone* tz = std::chrono::locate_zone("GMT");110 111  assert_equal(112      std::chrono::local_info(113          std::chrono::local_info::unique,114          std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 0s, 0min, "GMT"),115          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),116      tz->get_info(std::chrono::local_seconds::min()));117}118 119static void test_local_time_out_of_range() {120  // Fixed positive offset121  // Etc/GMT-1 1 - +01122 123  using namespace std::literals::chrono_literals;124  { // lower bound125    const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT-1");126 127    assert_equal(128        std::chrono::local_info(129            -1,130            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),131            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),132        tz->get_info(std::chrono::local_seconds::min()));133 134    assert_equal(135        std::chrono::local_info(136            -1,137            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),138            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),139        tz->get_info(std::chrono::local_seconds::min() + 59min + 59s));140 141    assert_equal(142        std::chrono::local_info(143            std::chrono::local_info::unique,144            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), 1h, 0min, "+01"),145            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),146        tz->get_info(std::chrono::local_seconds::min() + 1h));147  }148 149  { // upper bound150    const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");151 152    assert_equal(153        std::chrono::local_info(154            -2,155            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), -1h, 0min, "-01"),156            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),157        tz->get_info(std::chrono::local_seconds::max() - 1s));158 159    assert_equal(160        std::chrono::local_info(161            std::chrono::local_info::unique,162            std::chrono::sys_info(std::chrono::sys_seconds::min(), std::chrono::sys_seconds::max(), -1h, 0min, "-01"),163            std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),164        tz->get_info(std::chrono::local_seconds::max() - 1h - 1s));165  }166}167 168static void test_indian_kerguelen() {169  // One change, no rules, no dst changes.170 171  // Z Indian/Kerguelen 0 - -00 1950172  // 5 - +05173 174  using namespace std::literals::chrono_literals;175  const std::chrono::time_zone* tz = std::chrono::locate_zone("Indian/Kerguelen");176 177  assert_equal(178      std::chrono::local_info(179          std::chrono::local_info::unique,180          std::chrono::sys_info(181              std::chrono::sys_seconds::min(), to_sys_seconds(1950y, std::chrono::January, 1d), 0s, 0min, "-00"),182          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),183      tz->get_info(std::chrono::local_seconds::min()));184 185  assert_equal(186      std::chrono::local_info(187          std::chrono::local_info::nonexistent,188          std::chrono::sys_info(189              std::chrono::sys_seconds::min(), to_sys_seconds(1950y, std::chrono::January, 1d), 0s, 0min, "-00"),190          std::chrono::sys_info(191              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05")),192      tz->get_info(to_local_seconds(1950y, std::chrono::January, 1d)));193 194  assert_equal(195      std::chrono::local_info(196          std::chrono::local_info::unique,197          std::chrono::sys_info(198              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05"),199          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),200      tz->get_info(to_local_seconds(1950y, std::chrono::January, 1d, 5h)));201 202  assert_equal(203      std::chrono::local_info(204          std::chrono::local_info::unique,205          std::chrono::sys_info(206              to_sys_seconds(1950y, std::chrono::January, 1d), std::chrono::sys_seconds::max(), 5h, 0min, "+05"),207          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),208      tz->get_info(std::chrono::local_seconds::max() - 1s));209}210 211static void test_antarctica_rothera() {212  // One change, no rules, no dst changes213 214  // Z Antarctica/Rothera 0 - -00 1976 D215  // -3 - -03216 217  using namespace std::literals::chrono_literals;218  const std::chrono::time_zone* tz = std::chrono::locate_zone("Antarctica/Rothera");219 220  assert_equal(221      std::chrono::local_info(222          std::chrono::local_info::unique,223          std::chrono::sys_info(224              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),225          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),226      tz->get_info(std::chrono::local_seconds::min()));227 228  assert_equal(229      std::chrono::local_info(230          std::chrono::local_info::unique,231          std::chrono::sys_info(232              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),233          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),234      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 20h, 59min, 59s)));235 236  assert_equal(237      std::chrono::local_info(238          std::chrono::local_info::ambiguous,239          std::chrono::sys_info(240              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),241          std::chrono::sys_info(242              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03")),243      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 21h)));244 245  assert_equal(246      std::chrono::local_info(247          std::chrono::local_info::ambiguous,248          std::chrono::sys_info(249              std::chrono::sys_seconds::min(), to_sys_seconds(1976y, std::chrono::December, 1d), 0s, 0min, "-00"),250          std::chrono::sys_info(251              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03")),252      tz->get_info(to_local_seconds(1976y, std::chrono::November, 30d, 23h, 59min, 59s)));253 254  assert_equal(255      std::chrono::local_info(256          std::chrono::local_info::unique,257          std::chrono::sys_info(258              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),259          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),260      tz->get_info(to_local_seconds(1976y, std::chrono::December, 1d)));261 262  assert_equal(263      std::chrono::local_info(264          std::chrono::local_info::unique,265          std::chrono::sys_info(266              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),267          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),268      tz->get_info(std::chrono::local_seconds::max() - 3h - 1s));269 270  assert_equal(271      std::chrono::local_info(272          -2,273          std::chrono::sys_info(274              to_sys_seconds(1976y, std::chrono::December, 1d), std::chrono::sys_seconds::max(), -3h, 0min, "-03"),275          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),276      tz->get_info(std::chrono::local_seconds::max() - 1s));277}278 279static void test_asia_hong_kong() {280  // A more typical entry, first some hard-coded entires and then at the281  // end a rules based entry. This rule is valid for its entire period282  //283  // Z Asia/Hong_Kong 7:36:42 - LMT 1904 O 30 0:36:42284  // 8 - HKT 1941 Jun 15 3285  // 8 1 HKST 1941 O 1 4286  // 8 0:30 HKWT 1941 D 25287  // 9 - JST 1945 N 18 2288  // 8 HK HK%sT289  //290  // R HK 1946 o - Ap 21 0 1 S291  // R HK 1946 o - D 1 3:30s 0 -292  // R HK 1947 o - Ap 13 3:30s 1 S293  // R HK 1947 o - N 30 3:30s 0 -294  // R HK 1948 o - May 2 3:30s 1 S295  // R HK 1948 1952 - O Su>=28 3:30s 0 -296  // R HK 1949 1953 - Ap Su>=1 3:30 1 S297  // R HK 1953 1964 - O Su>=31 3:30 0 -298  // R HK 1954 1964 - Mar Su>=18 3:30 1 S299  // R HK 1965 1976 - Ap Su>=16 3:30 1 S300  // R HK 1965 1976 - O Su>=16 3:30 0 -301  // R HK 1973 o - D 30 3:30 1 S302  // R HK 1979 o - May 13 3:30 1 S303  // R HK 1979 o - O 21 3:30 0 -304 305  using namespace std::literals::chrono_literals;306  const std::chrono::time_zone* tz = std::chrono::locate_zone("Asia/Hong_Kong");307 308  assert_equal(309      std::chrono::local_info(310          -1,311          std::chrono::sys_info(312              std::chrono::sys_seconds::min(),313              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),314              7h + 36min + 42s,315              0min,316              "LMT"),317          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),318      tz->get_info(std::chrono::local_seconds::min()));319 320  assert_equal(321      std::chrono::local_info(322          -1,323          std::chrono::sys_info(324              std::chrono::sys_seconds::min(),325              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),326              7h + 36min + 42s,327              0min,328              "LMT"),329          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),330      tz->get_info(std::chrono::local_seconds::min() + 7h + 36min + 41s));331 332  assert_equal(333      std::chrono::local_info(334          std::chrono::local_info::unique,335          std::chrono::sys_info(336              std::chrono::sys_seconds::min(),337              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),338              7h + 36min + 42s,339              0min,340              "LMT"),341          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),342      tz->get_info(std::chrono::local_seconds::min() + 7h + 36min + 42s));343 344  assert_equal(345      std::chrono::local_info(346          std::chrono::local_info::unique,347          std::chrono::sys_info(348              std::chrono::sys_seconds::min(),349              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),350              7h + 36min + 42s,351              0min,352              "LMT"),353          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),354      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 36min, 41s)));355 356  assert_equal(357      std::chrono::local_info(358          std::chrono::local_info::nonexistent,359          std::chrono::sys_info(360              std::chrono::sys_seconds::min(),361              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),362              7h + 36min + 42s,363              0min,364              "LMT"),365          std::chrono::sys_info(366              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),367              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),368              8h,369              0min,370              "HKT")),371      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 36min, 42s)));372 373  assert_equal(374      std::chrono::local_info(375          std::chrono::local_info::nonexistent,376          std::chrono::sys_info(377              std::chrono::sys_seconds::min(),378              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),379              7h + 36min + 42s,380              0min,381              "LMT"),382          std::chrono::sys_info(383              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),384              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),385              8h,386              0min,387              "HKT")),388      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 0h, 59min, 59s)));389 390  assert_equal(391      std::chrono::local_info(392          std::chrono::local_info::unique,393          std::chrono::sys_info(394              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),395              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),396              8h,397              0min,398              "HKT"),399          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),400      tz->get_info(to_local_seconds(1904y, std::chrono::October, 30d, 1h)));401 402  assert_equal(403      std::chrono::local_info(404          std::chrono::local_info::unique,405          std::chrono::sys_info(406              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),407              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),408              8h,409              0min,410              "HKT"),411          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),412      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 2h, 59min, 59s)));413 414  assert_equal(415      std::chrono::local_info(416          std::chrono::local_info::nonexistent,417          std::chrono::sys_info(418              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),419              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),420              8h,421              0min,422              "HKT"),423          std::chrono::sys_info(424              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),425              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),426              9h,427              60min,428              "HKST")),429      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 3h)));430 431  assert_equal(432      std::chrono::local_info(433          std::chrono::local_info::nonexistent,434          std::chrono::sys_info(435              to_sys_seconds(1904y, std::chrono::October, 29d, 17h),436              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),437              8h,438              0min,439              "HKT"),440          std::chrono::sys_info(441              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),442              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),443              9h,444              60min,445              "HKST")),446      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 3h, 59min, 59s)));447 448  assert_equal(449      std::chrono::local_info(450          std::chrono::local_info::unique,451          std::chrono::sys_info(452              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),453              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),454              9h,455              60min,456              "HKST"),457          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),458      tz->get_info(to_local_seconds(1941y, std::chrono::June, 15d, 4h)));459 460  assert_equal(461      std::chrono::local_info(462          std::chrono::local_info::unique,463          std::chrono::sys_info(464              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),465              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),466              9h,467              60min,468              "HKST"),469          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),470      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 29min, 29s)));471 472  assert_equal(473      std::chrono::local_info(474          std::chrono::local_info::ambiguous,475          std::chrono::sys_info(476              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),477              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),478              9h,479              60min,480              "HKST"),481          std::chrono::sys_info(482              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),483              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),484              8h + 30min,485              30min,486              "HKWT")),487      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 30min)));488 489  assert_equal(490      std::chrono::local_info(491          std::chrono::local_info::ambiguous,492          std::chrono::sys_info(493              to_sys_seconds(1941y, std::chrono::June, 14d, 19h),494              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),495              9h,496              60min,497              "HKST"),498          std::chrono::sys_info(499              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),500              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),501              8h + 30min,502              30min,503              "HKWT")),504      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 3h, 59min, 59s)));505 506  assert_equal(507      std::chrono::local_info(508          std::chrono::local_info::unique,509          std::chrono::sys_info(510              to_sys_seconds(1941y, std::chrono::September, 30d, 19h),511              to_sys_seconds(1941y, std::chrono::December, 24d, 15h, 30min),512              8h + 30min,513              30min,514              "HKWT"),515          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),516      tz->get_info(to_local_seconds(1941y, std::chrono::October, 1d, 4h)));517}518 519static void test_europe_berlin() {520  // A more typical entry, first some hard-coded entires and then at the521  // end a rules based entry. This rule is valid for its entire period522  //523 524  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap525  // 1 c CE%sT 1945 May 24 2526  // 1 So CE%sT 1946527  // 1 DE CE%sT 1980528  // 1 E CE%sT529  //530  // R c 1916 o - Ap 30 23 1 S531  // R c 1916 o - O 1 1 0 -532  // R c 1917 1918 - Ap M>=15 2s 1 S533  // R c 1917 1918 - S M>=15 2s 0 -534  // R c 1940 o - Ap 1 2s 1 S535  // R c 1942 o - N 2 2s 0 -536  // R c 1943 o - Mar 29 2s 1 S537  // R c 1943 o - O 4 2s 0 -538  // R c 1944 1945 - Ap M>=1 2s 1 S539  // R c 1944 o - O 2 2s 0 -540  // R c 1945 o - S 16 2s 0 -541  // R c 1977 1980 - Ap Su>=1 2s 1 S542  // R c 1977 o - S lastSu 2s 0 -543  // R c 1978 o - O 1 2s 0 -544  // R c 1979 1995 - S lastSu 2s 0 -545  // R c 1981 ma - Mar lastSu 2s 1 S546  // R c 1996 ma - O lastSu 2s 0 -547  //548  // R So 1945 o - May 24 2 2 M549  // R So 1945 o - S 24 3 1 S550  // R So 1945 o - N 18 2s 0 -551  //552  // R DE 1946 o - Ap 14 2s 1 S553  // R DE 1946 o - O 7 2s 0 -554  // R DE 1947 1949 - O Su>=1 2s 0 -555  // R DE 1947 o - Ap 6 3s 1 S556  // R DE 1947 o - May 11 2s 2 M557  // R DE 1947 o - Jun 29 3 1 S558  // R DE 1948 o - Ap 18 2s 1 S559  // R DE 1949 o - Ap 10 2s 1 S560  //561  // R E 1977 1980 - Ap Su>=1 1u 1 S562  // R E 1977 o - S lastSu 1u 0 -563  // R E 1978 o - O 1 1u 0 -564  // R E 1979 1995 - S lastSu 1u 0 -565  // R E 1981 ma - Mar lastSu 1u 1 S566  // R E 1996 ma - O lastSu 1u 0 -567  //568  // Note the European Union decided to stop the seasonal change in569  // 2021. In 2023 seasonal changes are still in effect.570 571  using namespace std::literals::chrono_literals;572  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");573 574  assert_equal(575      std::chrono::local_info(576          -1,577          std::chrono::sys_info(578              std::chrono::sys_seconds::min(),579              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),580              53min + 28s,581              0min,582              "LMT"),583          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),584      tz->get_info(std::chrono::local_seconds::min()));585 586  assert_equal(587      std::chrono::local_info(588          -1,589          std::chrono::sys_info(590              std::chrono::sys_seconds::min(),591              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),592              53min + 28s,593              0min,594              "LMT"),595          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),596      tz->get_info(std::chrono::local_seconds::min() + 53min + 27s));597 598  assert_equal(599      std::chrono::local_info(600          std::chrono::local_info::unique,601          std::chrono::sys_info(602              std::chrono::sys_seconds::min(),603              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),604              53min + 28s,605              0min,606              "LMT"),607          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),608      tz->get_info(std::chrono::local_seconds::min() + 53min + 28s));609 610  assert_equal(611      std::chrono::local_info(612          std::chrono::local_info::unique,613          std::chrono::sys_info(614              std::chrono::sys_seconds::min(),615              to_sys_seconds(1893y, std::chrono::March, 31d, 23h, 6min, 32s),616              53min + 28s,617              0min,618              "LMT"),619          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),620      tz->get_info(to_local_seconds(1893y, std::chrono::March, 31d, 23h, 59min, 59s)));621 622  assert_equal(623      std::chrono::local_info(624          std::chrono::local_info::unique,625          std::chrono::sys_info(626              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),627              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),628              1h,629              0min,630              "CET"),631          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),632      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 2h, 59min, 59s)));633 634  assert_equal(635      std::chrono::local_info(636          std::chrono::local_info::nonexistent,637          std::chrono::sys_info(638              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),639              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),640              1h,641              0min,642              "CET"),643          std::chrono::sys_info(644              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),645              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),646              2h,647              60min,648              "CEST")),649      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 3h)));650 651  assert_equal(652      std::chrono::local_info(653          std::chrono::local_info::nonexistent,654          std::chrono::sys_info(655              to_sys_seconds(1946y, std::chrono::October, 7d, 1h),656              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),657              1h,658              0min,659              "CET"),660          std::chrono::sys_info(661              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),662              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),663              2h,664              60min,665              "CEST")),666      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 3h, 59min, 59s)));667 668  assert_equal(669      std::chrono::local_info(670          std::chrono::local_info::unique,671          std::chrono::sys_info(672              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),673              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),674              2h,675              60min,676              "CEST"),677          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),678      tz->get_info(to_local_seconds(1947y, std::chrono::April, 6d, 4h)));679 680  assert_equal(681      std::chrono::local_info(682          std::chrono::local_info::unique,683          std::chrono::sys_info(684              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),685              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),686              2h,687              60min,688              "CEST"),689          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),690      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 2h, 59min, 59s)));691 692  assert_equal(693      std::chrono::local_info(694          std::chrono::local_info::nonexistent,695          std::chrono::sys_info(696              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),697              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),698              2h,699              60min,700              "CEST"),701          std::chrono::sys_info(702              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),703              to_sys_seconds(1947y, std::chrono::June, 29d),704              3h,705              120min,706              "CEMT")),707      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 3h)));708 709  assert_equal(710      std::chrono::local_info(711          std::chrono::local_info::nonexistent,712          std::chrono::sys_info(713              to_sys_seconds(1947y, std::chrono::April, 6d, 2h),714              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),715              2h,716              60min,717              "CEST"),718          std::chrono::sys_info(719              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),720              to_sys_seconds(1947y, std::chrono::June, 29d),721              3h,722              120min,723              "CEMT")),724      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 3h, 59min, 59s)));725 726  assert_equal(727      std::chrono::local_info(728          std::chrono::local_info::unique,729          std::chrono::sys_info(730              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),731              to_sys_seconds(1947y, std::chrono::June, 29d),732              3h,733              120min,734              "CEMT"),735          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),736      tz->get_info(to_local_seconds(1947y, std::chrono::May, 11d, 4h)));737 738  assert_equal(739      std::chrono::local_info(740          std::chrono::local_info::unique,741          std::chrono::sys_info(742              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),743              to_sys_seconds(1947y, std::chrono::June, 29d),744              3h,745              120min,746              "CEMT"),747          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),748      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 1h, 59min, 59s)));749 750  assert_equal(751      std::chrono::local_info(752          std::chrono::local_info::ambiguous,753          std::chrono::sys_info(754              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),755              to_sys_seconds(1947y, std::chrono::June, 29d),756              3h,757              120min,758              "CEMT"),759          std::chrono::sys_info(760              to_sys_seconds(1947y, std::chrono::June, 29d),761              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),762              2h,763              60min,764              "CEST")),765      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 2h)));766 767  assert_equal(768      std::chrono::local_info(769          std::chrono::local_info::ambiguous,770          std::chrono::sys_info(771              to_sys_seconds(1947y, std::chrono::May, 11d, 1h),772              to_sys_seconds(1947y, std::chrono::June, 29d),773              3h,774              120min,775              "CEMT"),776          std::chrono::sys_info(777              to_sys_seconds(1947y, std::chrono::June, 29d),778              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),779              2h,780              60min,781              "CEST")),782      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 2h, 59min, 59s)));783 784  assert_equal(785      std::chrono::local_info(786          std::chrono::local_info::unique,787          std::chrono::sys_info(788              to_sys_seconds(1947y, std::chrono::June, 29d),789              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),790              2h,791              60min,792              "CEST"),793          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),794      tz->get_info(to_local_seconds(1947y, std::chrono::June, 29d, 3h)));795 796  assert_equal(797      std::chrono::local_info(798          std::chrono::local_info::unique,799          std::chrono::sys_info(800              to_sys_seconds(1947y, std::chrono::June, 29d),801              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),802              2h,803              60min,804              "CEST"),805          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),806      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 1h, 59min, 59s)));807 808  assert_equal(809      std::chrono::local_info(810          std::chrono::local_info::ambiguous,811          std::chrono::sys_info(812              to_sys_seconds(1947y, std::chrono::June, 29d),813              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),814              2h,815              60min,816              "CEST"),817          std::chrono::sys_info(818              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),819              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),820              1h,821              0min,822              "CET")),823      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 2h)));824 825  assert_equal(826      std::chrono::local_info(827          std::chrono::local_info::ambiguous,828          std::chrono::sys_info(829              to_sys_seconds(1947y, std::chrono::June, 29d),830              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),831              2h,832              60min,833              "CEST"),834          std::chrono::sys_info(835              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),836              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),837              1h,838              0min,839              "CET")),840      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 2h, 59min, 59s)));841 842  assert_equal(843      std::chrono::local_info(844          std::chrono::local_info::unique,845          std::chrono::sys_info(846              to_sys_seconds(1947y, std::chrono::October, 5d, 1h),847              to_sys_seconds(1948y, std::chrono::April, 18d, 1h),848              1h,849              0min,850              "CET"),851          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),852      tz->get_info(to_local_seconds(1947y, std::chrono::October, 5d, 3h)));853}854 855static void test_europe_dublin() {856  // Z Europe/Dublin -0:25:21 - LMT 1880 Au 2857  // -0:25:21 - DMT 1916 May 21 2s858  // -0:25:21 1 IST 1916 O 1 2s859  // 0 G %s 1921 D 6860  // ...861  //862  // R G 1916 o - May 21 2s 1 BST863  // R G 1916 o - O 1 2s 0 GMT864  // R G 1917 o - Ap 8 2s 1 BST865  // ...866 867  using namespace std::literals::chrono_literals;868  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Dublin");869 870  assert_equal(871      std::chrono::local_info(872          std::chrono::local_info::unique,873          std::chrono::sys_info(874              std::chrono::sys_seconds::min(),875              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),876              -(25min + 21s),877              0min,878              "LMT"),879          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),880      tz->get_info(std::chrono::local_seconds::min()));881 882  assert_equal(883      std::chrono::local_info(884          std::chrono::local_info::unique,885          std::chrono::sys_info(886              std::chrono::sys_seconds::min(),887              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),888              -(25min + 21s),889              0min,890              "LMT"),891          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),892      tz->get_info(to_local_seconds(1880y, std::chrono::August, 1d, 23h, 59min, 59s)));893 894  assert_equal(895      std::chrono::local_info(896          std::chrono::local_info::unique,897          std::chrono::sys_info(898              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),899              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),900              -(25min + 21s),901              0min,902              "DMT"),903          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),904      tz->get_info(to_local_seconds(1880y, std::chrono::August, 2d)));905 906  assert_equal(907      std::chrono::local_info(908          std::chrono::local_info::unique,909          std::chrono::sys_info(910              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),911              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),912              -(25min + 21s),913              0min,914              "DMT"),915          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),916      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 1h, 59min, 59s)));917 918  assert_equal(919      std::chrono::local_info(920          std::chrono::local_info::nonexistent,921          std::chrono::sys_info(922              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),923              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),924              -(25min + 21s),925              0min,926              "DMT"),927          std::chrono::sys_info(928              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),929              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),930              34min + 39s,931              60min,932              "IST")),933      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 2h)));934 935  assert_equal(936      std::chrono::local_info(937          std::chrono::local_info::nonexistent,938          std::chrono::sys_info(939              to_sys_seconds(1880y, std::chrono::August, 2d, 0h, 25min, 21s),940              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),941              -(25min + 21s),942              0min,943              "DMT"),944          std::chrono::sys_info(945              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),946              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),947              34min + 39s,948              60min,949              "IST")),950      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 2h, 59min, 59s)));951 952  assert_equal(953      std::chrono::local_info(954          std::chrono::local_info::unique,955          std::chrono::sys_info(956              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),957              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),958              34min + 39s,959              60min,960              "IST"),961          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),962      tz->get_info(to_local_seconds(1916y, std::chrono::May, 21d, 6h)));963 964  assert_equal(965      std::chrono::local_info(966          std::chrono::local_info::unique,967          std::chrono::sys_info(968              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),969              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),970              34min + 39s,971              60min,972              "IST"),973          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),974      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 2h, 25min, 20s)));975 976  assert_equal(977      std::chrono::local_info(978          std::chrono::local_info::ambiguous,979          std::chrono::sys_info(980              to_sys_seconds(1916y, std::chrono::May, 21d, 2h, 25min, 21s),981              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),982              34min + 39s,983              60min,984              "IST"),985          std::chrono::sys_info(986              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),987              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),988              0s,989              0min,990              "GMT")),991      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 2h, 59min, 59s)));992 993  assert_equal(994      std::chrono::local_info(995          std::chrono::local_info::unique,996          std::chrono::sys_info(997              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),998              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),999              0s,1000              0min,1001              "GMT"),1002          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1003      tz->get_info(to_local_seconds(1916y, std::chrono::October, 1d, 3h)));1004 1005  assert_equal(1006      std::chrono::local_info(1007          std::chrono::local_info::unique,1008          std::chrono::sys_info(1009              to_sys_seconds(1916y, std::chrono::October, 1d, 02h, 25min, 21s),1010              to_sys_seconds(1917y, std::chrono::April, 8d, 2h),1011              0s,1012              0min,1013              "GMT"),1014          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1015      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 1h, 59min, 59s)));1016}1017 1018static void test_america_st_johns() {1019  // A more typical entry,1020  // Uses letters both when DST is active and not and has multiple1021  // letters. Uses negative offsets.1022  // Switches several times between their own and Canadian rules1023  // Switches the stdoff from -3:30:52 to -3:30 while observing the same rule1024 1025  // Z America/St_Johns -3:30:52 - LMT 18841026  // -3:30:52 j N%sT 19181027  // -3:30:52 C N%sT 19191028  // ...1029  //1030  // R j 1917 o - Ap 8 2 1 D1031  // R j 1917 o - S 17 2 0 S1032  // R j 1919 o - May 5 23 1 D1033  // R j 1919 o - Au 12 23 0 S1034  // R j 1920 1935 - May Su>=1 23 1 D1035  // ...1036  //1037  // R C 1918 o - Ap 14 2 1 D1038  // R C 1918 o - O 27 2 0 S1039  // R C 1942 o - F 9 2 1 W1040  // ...1041 1042  using namespace std::literals::chrono_literals;1043  const std::chrono::time_zone* tz = std::chrono::locate_zone("America/St_Johns");1044 1045  assert_equal(1046      std::chrono::local_info(1047          std::chrono::local_info::unique,1048          std::chrono::sys_info(1049              std::chrono::sys_seconds::min(),1050              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1051              -(3h + 30min + 52s),1052              0min,1053              "LMT"),1054          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1055      tz->get_info(std::chrono::local_seconds::min()));1056 1057  assert_equal(1058      std::chrono::local_info(1059          std::chrono::local_info::unique,1060          std::chrono::sys_info(1061              std::chrono::sys_seconds::min(),1062              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1063              -(3h + 30min + 52s),1064              0min,1065              "LMT"),1066          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1067      tz->get_info(to_local_seconds(1883y, std::chrono::December, 31d, 23h, 59min, 59s)));1068 1069  assert_equal(1070      std::chrono::local_info(1071          std::chrono::local_info::unique,1072          std::chrono::sys_info(1073              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1074              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1075              -(3h + 30min + 52s),1076              0min,1077              "NST"),1078          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1079      tz->get_info(to_local_seconds(1884y, std::chrono::January, 1d)));1080 1081  assert_equal(1082      std::chrono::local_info(1083          std::chrono::local_info::unique,1084          std::chrono::sys_info(1085              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1086              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1087              -(3h + 30min + 52s),1088              0min,1089              "NST"),1090          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1091      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 1h, 59min, 59s)));1092 1093  assert_equal(1094      std::chrono::local_info(1095          std::chrono::local_info::nonexistent,1096          std::chrono::sys_info(1097              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1098              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1099              -(3h + 30min + 52s),1100              0min,1101              "NST"),1102          std::chrono::sys_info(1103              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1104              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1105              -(2h + 30min + 52s),1106              60min,1107              "NDT")),1108      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 2h)));1109 1110  assert_equal(1111      std::chrono::local_info(1112          std::chrono::local_info::nonexistent,1113          std::chrono::sys_info(1114              to_sys_seconds(1884y, std::chrono::January, 1d, 3h, 30min, 52s),1115              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1116              -(3h + 30min + 52s),1117              0min,1118              "NST"),1119          std::chrono::sys_info(1120              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1121              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1122              -(2h + 30min + 52s),1123              60min,1124              "NDT")),1125      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 2h, 59min, 59s)));1126 1127  assert_equal(1128      std::chrono::local_info(1129          std::chrono::local_info::unique,1130          std::chrono::sys_info(1131              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1132              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1133              -(2h + 30min + 52s),1134              60min,1135              "NDT"),1136          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1137      tz->get_info(to_local_seconds(1917y, std::chrono::April, 8d, 3h)));1138 1139  assert_equal(1140      std::chrono::local_info(1141          std::chrono::local_info::unique,1142          std::chrono::sys_info(1143              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1144              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1145              -(2h + 30min + 52s),1146              60min,1147              "NDT"),1148          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1149      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 0h, 59min, 59s)));1150 1151  assert_equal(1152      std::chrono::local_info(1153          std::chrono::local_info::ambiguous,1154          std::chrono::sys_info(1155              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1156              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1157              -(2h + 30min + 52s),1158              60min,1159              "NDT"),1160          std::chrono::sys_info(1161              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1162              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),1163              -(3h + 30min + 52s),1164              0min,1165              "NST")),1166      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 1h)));1167 1168  assert_equal(1169      std::chrono::local_info(1170          std::chrono::local_info::ambiguous,1171          std::chrono::sys_info(1172              to_sys_seconds(1917y, std::chrono::April, 8d, 5h, 30min, 52s),1173              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1174              -(2h + 30min + 52s),1175              60min,1176              "NDT"),1177          std::chrono::sys_info(1178              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1179              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),1180              -(3h + 30min + 52s),1181              0min,1182              "NST")),1183      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 1h, 59min, 59s)));1184 1185  assert_equal(1186      std::chrono::local_info(1187          std::chrono::local_info::unique,1188          std::chrono::sys_info(1189              to_sys_seconds(1917y, std::chrono::September, 17d, 4h, 30min, 52s),1190              to_sys_seconds(1918y, std::chrono::April, 14d, 5h, 30min, 52s),1191              -(3h + 30min + 52s),1192              0min,1193              "NST"),1194          std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1195      tz->get_info(to_local_seconds(1917y, std::chrono::September, 17d, 2h)));1196}1197 1198static void validate_transitions(const std::chrono::time_zone& zone) {1199  using namespace std::literals::chrono_literals;1200 1201  constexpr auto begin = std::chrono::time_point_cast<std::chrono::seconds>(1202      static_cast<std::chrono::sys_days>(std::chrono::year_month_day{first, std::chrono::January, 1d}));1203  constexpr auto end = std::chrono::time_point_cast<std::chrono::seconds>(1204      static_cast<std::chrono::sys_days>(std::chrono::year_month_day{last, std::chrono::January, 1d}));1205 1206  // Builds the set of sys_info objects for the selected time range.1207  std::vector<std::chrono::sys_info> input;1208  std::chrono::sys_seconds s = begin;1209  do {1210    input.emplace_back(zone.get_info(s));1211    s = input.back().end;1212  } while (s < end);1213 1214  for (auto previous = input.begin(), next = previous + 1; next != input.end(); ++previous, ++next) {1215    // Now iterates to all adjacent objects.1216    // For every transition gets the locate time of the1217    // - end of the first          (a)1218    // - the start if the second   (b)1219    // Depending on the difference between 'a' and 'b' different tests are done.1220    std::chrono::local_seconds end_previous{previous->end.time_since_epoch() + previous->offset};1221    std::chrono::local_seconds begin_next{next->begin.time_since_epoch() + next->offset};1222 1223    if (end_previous == begin_next) {1224      // unique transition1225      // a |------------|1226      // b              |----------|1227      //                T1228      assert_equal(std::chrono::local_info(1229                       std::chrono::local_info::unique,1230                       *previous,1231                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1232                   zone.get_info(end_previous - 1s));1233 1234      assert_equal(std::chrono::local_info(1235                       std::chrono::local_info::unique,1236                       *next,1237                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1238                   zone.get_info(begin_next));1239 1240    } else if (end_previous < begin_next) {1241      // non-existent transition1242      // a |------------|1243      // b                 |----------|1244      //                T  T1245      assert_equal(std::chrono::local_info(1246                       std::chrono::local_info::unique,1247                       *previous,1248                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1249                   zone.get_info(end_previous - 1s));1250 1251      assert_equal(std::chrono::local_info(std::chrono::local_info::nonexistent, *previous, *next),1252                   zone.get_info(end_previous));1253 1254      assert_equal(std::chrono::local_info(std::chrono::local_info::nonexistent, *previous, *next),1255                   zone.get_info(begin_next - 1s));1256 1257      assert_equal(std::chrono::local_info(1258                       std::chrono::local_info::unique,1259                       *next,1260                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1261                   zone.get_info(begin_next));1262 1263    } else {1264      // ambiguous transition1265      // a |------------|1266      // b           |----------|1267      //             T  T1268      assert_equal(std::chrono::local_info(1269                       std::chrono::local_info::unique,1270                       *previous,1271                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1272                   zone.get_info(begin_next - 1s));1273 1274      assert_equal(std::chrono::local_info(std::chrono::local_info::ambiguous, *previous, *next),1275                   zone.get_info(begin_next));1276 1277      assert_equal(std::chrono::local_info(std::chrono::local_info::ambiguous, *previous, *next),1278                   zone.get_info(end_previous - 1s));1279 1280      assert_equal(std::chrono::local_info(1281                       std::chrono::local_info::unique,1282                       *next,1283                       std::chrono::sys_info(std::chrono::sys_seconds(0s), std::chrono::sys_seconds(0s), 0s, 0min, "")),1284                   zone.get_info(end_previous));1285    }1286  }1287}1288 1289int main(int, const char**) {1290  test_gmt();1291  test_local_time_out_of_range();1292  test_indian_kerguelen();1293  test_antarctica_rothera();1294 1295  test_asia_hong_kong();1296  test_europe_berlin();1297  test_europe_dublin();1298  test_america_st_johns();1299 1300  const std::chrono::tzdb& tzdb = std::chrono::get_tzdb();1301  for (const auto& zone : tzdb.zones) {1302    validate_transitions(zone);1303  }1304 1305  return 0;1306}1307