brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · b2dbdb1 Raw
161 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 12// XFAIL: libcpp-has-no-experimental-tzdb13// XFAIL: availability-tzdb-missing14 15// <chrono>16 17// class time_zone;18 19// template <class _Duration>20//   sys_time<common_type_t<Duration, seconds>>21//     to_sys(const local_time<Duration>& tp, choose z) const;22 23#include <chrono>24#include <format>25#include <cassert>26#include <string_view>27 28#include "test_macros.h"29 30// Tests unique conversions. To make sure the test is does not depend on changes31// in the database it uses a time zone with a fixed offset.32static void test_unique() {33  using namespace std::literals::chrono_literals;34 35  const std::chrono::time_zone* tz = std::chrono::locate_zone("Etc/GMT+1");36 37  assert(tz->to_sys(std::chrono::local_time<std::chrono::nanoseconds>{-1ns}, std::chrono::choose::earliest) ==38         std::chrono::sys_time<std::chrono::nanoseconds>{-1ns + 1h});39 40  assert(tz->to_sys(std::chrono::local_time<std::chrono::microseconds>{0us}, std::chrono::choose::latest) ==41         std::chrono::sys_time<std::chrono::microseconds>{1h});42 43  assert(tz->to_sys(44             std::chrono::local_time<std::chrono::seconds>{45                 (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},46             std::chrono::choose::earliest) ==47         std::chrono::sys_time<std::chrono::seconds>{48             (std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch() + 1h});49 50  // sys_time<common_type_t<Duration, seconds>> is seconds for the larger types51  assert(tz->to_sys(52             std::chrono::local_time<std::chrono::days>{53                 (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},54             std::chrono::choose::latest) ==55         std::chrono::sys_time<std::chrono::seconds>{56             (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch() + 1h});57 58  assert(tz->to_sys(std::chrono::local_time<std::chrono::weeks>{}, std::chrono::choose::earliest) ==59         std::chrono::sys_time<std::chrono::seconds>{60             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});61 62  // Note months and years cannot be streamed; however these functions don't63  // throw an exception and thus can be used.64  assert(tz->to_sys(std::chrono::local_time<std::chrono::months>{}, std::chrono::choose::latest) ==65         std::chrono::sys_time<std::chrono::seconds>{66             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});67 68  assert(tz->to_sys(std::chrono::local_time<std::chrono::years>{}, std::chrono::choose::earliest) ==69         std::chrono::sys_time<std::chrono::seconds>{70             (std::chrono::sys_days{std::chrono::January / 1 / 1970}).time_since_epoch() + 1h});71}72 73// Tests non-existant conversions.74static void test_nonexistent() {75  using namespace std::literals::chrono_literals;76 77  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");78 79  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap80  // ...81  // 1 DE CE%sT 198082  // 1 E CE%sT83  //84  // ...85  // R E 1981 ma - Mar lastSu 1u 1 S86  // R E 1996 ma - O lastSu 1u 0 -87 88  // Pick an historic date where it's well known what the time zone rules were.89  // This makes it unlikely updates to the database change these rules.90  std::chrono::local_time<std::chrono::seconds> time{91      (std::chrono::sys_days{std::chrono::March / 30 / 1986} + 2h).time_since_epoch()};92 93  std::chrono::sys_seconds expected{time.time_since_epoch() - 1h};94 95  // Validates whether the database did not change.96  std::chrono::local_info info = tz->get_info(time);97  assert(info.result == std::chrono::local_info::nonexistent);98 99  assert(tz->to_sys(time + 0ns, std::chrono::choose::earliest) == expected);100  assert(tz->to_sys(time + 0us, std::chrono::choose::latest) == expected);101  assert(tz->to_sys(time + 0ms, std::chrono::choose::earliest) == expected);102  assert(tz->to_sys(time + 0s, std::chrono::choose::latest) == expected);103 104  // The entire nonexisting hour should map to the same time.105  // For nonexistant the value of std::chrono::choose has no effect.106  assert(tz->to_sys(time + 1s, std::chrono::choose::earliest) == expected);107  assert(tz->to_sys(time + 1min, std::chrono::choose::latest) == expected);108  assert(tz->to_sys(time + 30min, std::chrono::choose::earliest) == expected);109  assert(tz->to_sys(time + 59min + 59s, std::chrono::choose::latest) == expected);110}111 112// Tests ambiguous conversions.113static void test_ambiguous() {114  using namespace std::literals::chrono_literals;115 116  const std::chrono::time_zone* tz = std::chrono::locate_zone("Europe/Berlin");117 118  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap119  // ...120  // 1 DE CE%sT 1980121  // 1 E CE%sT122  //123  // ...124  // R E 1981 ma - Mar lastSu 1u 1 S125  // R E 1996 ma - O lastSu 1u 0 -126 127  // Pick an historic date where it's well known what the time zone rules were.128  // This makes it unlikely updates to the database change these rules.129  std::chrono::local_time<std::chrono::seconds> time{130      (std::chrono::sys_days{std::chrono::September / 28 / 1986} + 2h).time_since_epoch()};131 132  std::chrono::sys_seconds earlier{time.time_since_epoch() - 2h};133  std::chrono::sys_seconds later{time.time_since_epoch() - 1h};134 135  // Validates whether the database did not change.136  std::chrono::local_info info = tz->get_info(time);137  assert(info.result == std::chrono::local_info::ambiguous);138 139  assert(tz->to_sys(time + 0ns, std::chrono::choose::earliest) == earlier);140  assert(tz->to_sys(time + 0us, std::chrono::choose::latest) == later);141  assert(tz->to_sys(time + 0ms, std::chrono::choose::earliest) == earlier);142  assert(tz->to_sys(time + 0s, std::chrono::choose::latest) == later);143 144  // Test times in the ambiguous hour145  assert(tz->to_sys(time + 1s, std::chrono::choose::earliest) == earlier + 1s);146  assert(tz->to_sys(time + 1min, std::chrono::choose::latest) == later + 1min);147  assert(tz->to_sys(time + 30min, std::chrono::choose::earliest) == earlier + 30min);148  assert(tz->to_sys(time + 59min + 59s, std::chrono::choose::latest) == later + 59min + 59s);149}150 151// This test does the basic validations of this function. The library function152// uses `local_info get_info(const local_time<Duration>& tp)` as implementation153// detail. The get_info function does extensive testing of the data.154int main(int, char**) {155  test_unique();156  test_nonexistent();157  test_ambiguous();158 159  return 0;160}161