brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.6 KiB · 3f9ca57 Raw
253 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// template<class Duration, class TimeZonePtr = const time_zone*>18// class zoned_time;19//20// zoned_time& operator=(const local_time<Duration>& st);21 22// TODO TZDB Investigate the issues in this test, this seems like23// a design issue of the class.24//25// [time.zone.zonedtime.members]/326//   Effects: After assignment, get_local_time() == lt.27//   This assignment has no effect on the return value of get_time_zone().28//29// The test cases describe the issues.30 31#include <cassert>32#include <chrono>33#include <concepts>34#include <type_traits>35 36#include "test_macros.h"37 38namespace cr = std::chrono;39 40// Tests unique conversions. To make sure the test is does not depend on changes41// in the database it uses a time zone with a fixed offset.42static void test_unique() {43  // common_type_t<duration, seconds> -> duration44  {45    using duration         = cr::nanoseconds;46    using sys_time_point   = cr::sys_time<duration>;47    using local_time_point = cr::local_time<duration>;48    using zoned_time       = cr::zoned_time<duration>;49    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};50 51    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));52    assert(zt.get_sys_time() == sys_time_point{duration{42}});53    assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}});54 55    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};56    assert(&result == &zt);57    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));58    assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}});59    assert(zt.get_local_time() == local_time_point{duration{99}});60  }61  {62    using duration         = cr::microseconds;63    using sys_time_point   = cr::sys_time<duration>;64    using local_time_point = cr::local_time<duration>;65    using zoned_time       = cr::zoned_time<duration>;66    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};67 68    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));69    assert(zt.get_sys_time() == sys_time_point{duration{42}});70    assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}});71 72    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};73    assert(&result == &zt);74    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));75    assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}});76    assert(zt.get_local_time() == local_time_point{duration{99}});77  }78  {79    using duration         = cr::milliseconds;80    using sys_time_point   = cr::sys_time<duration>;81    using local_time_point = cr::local_time<duration>;82    using zoned_time       = cr::zoned_time<duration>;83    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};84 85    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));86    assert(zt.get_sys_time() == sys_time_point{duration{42}});87    assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}});88 89    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};90    assert(&result == &zt);91    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));92    assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}});93    assert(zt.get_local_time() == local_time_point{duration{99}});94  }95  // common_type_t<seconds, seconds> -> seconds96  {97    using duration         = cr::seconds;98    using sys_time_point   = cr::sys_time<duration>;99    using local_time_point = cr::local_time<duration>;100    using zoned_time       = cr::zoned_time<duration>;101    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};102 103    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));104    assert(zt.get_sys_time() == sys_time_point{duration{42}});105    assert(zt.get_local_time() == local_time_point{duration{42} - cr::hours{1}});106 107    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};108    assert(&result == &zt);109    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));110    assert(zt.get_sys_time() == sys_time_point{duration{99} + cr::hours{1}});111    assert(zt.get_local_time() == local_time_point{duration{99}});112  }113  // common_type_t<duration, seconds> -> seconds114  {115    using duration         = cr::days;116    using sys_time_point   = cr::sys_time<duration>;117    using local_time_point = cr::local_time<duration>;118    using zoned_time       = cr::zoned_time<duration>;119    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};120 121    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));122    assert(zt.get_sys_time() == cr::sys_seconds{duration{42}});123    assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}});124 125    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};126    assert(&result == &zt);127    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));128    assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}});129    assert(zt.get_local_time() == cr::local_seconds{duration{99}});130  }131  {132    using duration         = cr::weeks;133    using sys_time_point   = cr::sys_time<duration>;134    using local_time_point = cr::local_time<duration>;135    using zoned_time       = cr::zoned_time<duration>;136    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};137 138    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));139    assert(zt.get_sys_time() == cr::sys_seconds{duration{42}});140    assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}});141 142    std::same_as<zoned_time&> decltype(auto) result = zt = local_time_point{duration{99}};143    assert(&result == &zt);144    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));145    assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}});146    assert(zt.get_local_time() == cr::local_seconds{duration{99}});147  }148  /* This does not work; due to using __tp_ = __zone_->to_sys(__tp);149   * Here the ambiguous/non-existent exception can't stream months and years,150   * leading to a compilation error.151  {152    using duration         = cr::months;153    using sys_time_point   = cr::sys_time<duration>;154    using local_time_point = cr::local_time<duration>;155    using zoned_time       = cr::zoned_time<duration>;156    zoned_time zt{"Etc/GMT+1", sys_time_point{duration{42}}};157 158    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));159    assert(zt.get_sys_time() == cr::sys_seconds{duration{42}});160    assert(zt.get_local_time() == cr::local_seconds{duration{42} - cr::hours{1}});161 162    std::same_as<zoned_time&> decltype(auto) result= zt = local_time_point{duration{99}};163    assert(&result == &zt);164    assert(zt.get_time_zone() == cr::locate_zone("Etc/GMT+1"));165    assert(zt.get_sys_time() == cr::sys_seconds{duration{99} + cr::hours{1}});166    assert(zt.get_local_time() == cr::local_seconds{duration{99}});167  } */168}169 170// Tests non-existent conversions.171static void test_nonexistent() {172#ifndef TEST_HAS_NO_EXCEPTIONS173  using namespace std::literals::chrono_literals;174 175  const cr::time_zone* tz = cr::locate_zone("Europe/Berlin");176 177  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap178  // ...179  // 1 DE CE%sT 1980180  // 1 E CE%sT181  //182  // ...183  // R E 1981 ma - Mar lastSu 1u 1 S184  // R E 1996 ma - O lastSu 1u 0 -185 186  // Pick an historic date where it's well known what the time zone rules were.187  // This makes it unlikely updates to the database change these rules.188  cr::local_time<cr::seconds> time{(cr::sys_days{cr::March / 30 / 1986} + 2h + 30min).time_since_epoch()};189 190  using duration   = cr::seconds;191  using zoned_time = cr::zoned_time<duration>;192  zoned_time zt{tz};193 194  bool thrown = false;195  try {196    std::same_as<zoned_time&> decltype(auto) result = zt = time;197    assert(&result == &zt);198  } catch (const cr::nonexistent_local_time&) {199    thrown = true;200  }201  // There is no system type that can represent the current local time. So the202  // assertion passes. The current implementation throws an exception too.203  assert(zt.get_local_time() != time);204  assert(thrown);205#endif // TEST_HAS_NO_EXCEPTIONS206}207 208// Tests ambiguous conversions.209static void test_ambiguous() {210#ifndef TEST_HAS_NO_EXCEPTIONS211  using namespace std::literals::chrono_literals;212 213  const cr::time_zone* tz = cr::locate_zone("Europe/Berlin");214 215  // Z Europe/Berlin 0:53:28 - LMT 1893 Ap216  // ...217  // 1 DE CE%sT 1980218  // 1 E CE%sT219  //220  // ...221  // R E 1981 ma - Mar lastSu 1u 1 S222  // R E 1996 ma - O lastSu 1u 0 -223 224  // Pick an historic date where it's well known what the time zone rules were.225  // This makes it unlikely updates to the database change these rules.226  cr::local_time<cr::seconds> time{(cr::sys_days{cr::September / 28 / 1986} + 2h + 30min).time_since_epoch()};227 228  using duration   = cr::seconds;229  using zoned_time = cr::zoned_time<duration>;230  zoned_time zt{tz};231 232  bool thrown = false;233  try {234    std::same_as<zoned_time&> decltype(auto) result = zt = time;235    assert(&result == &zt);236  } catch (const cr::ambiguous_local_time&) {237    thrown = true;238  }239  // There is no system type that can represent the current local time. So the240  // assertion passes. The current implementation throws an exception too.241  assert(zt.get_local_time() != time);242  assert(thrown);243#endif // TEST_HAS_NO_EXCEPTIONS244}245 246int main(int, char**) {247  test_unique();248  test_nonexistent();249  test_ambiguous();250 251  return 0;252}253