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-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
11
12// XFAIL: libcpp-has-no-experimental-tzdb
13// XFAIL: availability-tzdb-missing
14
15// <chrono>
16
17// class nonexistent_local_time
18//
19// template<class Duration>
20// nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
21
22#include <chrono>
23#include <string_view>
24
25#include "assert_macros.h"
26#include "concat_macros.h"
27
28template <class Duration>
29static void
30test(const std::chrono::local_time<Duration>& tp, const std::chrono::local_info& i, std::string_view expected) {
31 std::chrono::nonexistent_local_time exception{tp, i};
32 std::string_view result = exception.what();
33 TEST_REQUIRE(result == expected,
34 TEST_WRITE_CONCATENATED("Expected output\n", expected, "\n\nActual output\n", result, '\n'));
35}
36
37// The constructor constructs the runtime_error base class with a specific
38// message. This implicitly tests what() too, since that is inherited from
39// runtime_error there is no separate test for what().
40int main(int, char**) {
41 using namespace std::literals::chrono_literals;
42
43 // There is no requirement on the ordering of PREV and NEXT so an "invalid"
44 // gap is allowed. All tests with negative dates use the same order as
45 // positive tests.
46
47 test(std::chrono::local_time<std::chrono::nanoseconds>{-1ns},
48 std::chrono::local_info{
49 std::chrono::local_info::nonexistent,
50 std::chrono::sys_info{
51 std::chrono::sys_days{std::chrono::September / 1 / 1969},
52 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
53 0s,
54 0min,
55 "PREV"},
56 std::chrono::sys_info{
57 std::chrono::sys_days{std::chrono::January / 1 / 1970},
58 std::chrono::sys_days{std::chrono::March / 1 / 1970},
59 1h,
60 60min,
61 "NEXT"}},
62 R"(1969-12-31 23:59:59.999999999 is in a gap between
631969-12-31 23:00:00 PREV and
641970-01-01 01:00:00 NEXT which are both equivalent to
651969-12-31 23:00:00 UTC)");
66
67 test(std::chrono::local_time<std::chrono::microseconds>{0us},
68 std::chrono::local_info{
69 std::chrono::local_info::nonexistent,
70 std::chrono::sys_info{
71 std::chrono::sys_days{std::chrono::September / 1 / 1969},
72 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
73 0s,
74 0min,
75 "PREV"},
76 std::chrono::sys_info{
77 std::chrono::sys_days{std::chrono::January / 1 / 1970},
78 std::chrono::sys_days{std::chrono::March / 1 / 1970},
79 1h,
80 60min,
81 "NEXT"}},
82 R"(1970-01-01 00:00:00.000000 is in a gap between
831969-12-31 23:00:00 PREV and
841970-01-01 01:00:00 NEXT which are both equivalent to
851969-12-31 23:00:00 UTC)");
86
87 test(std::chrono::local_time<std::chrono::milliseconds>{1ms},
88 std::chrono::local_info{
89 std::chrono::local_info::nonexistent,
90 std::chrono::sys_info{
91 std::chrono::sys_days{std::chrono::September / 1 / 1969},
92 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
93 0s,
94 0min,
95 "PREV"},
96 std::chrono::sys_info{
97 std::chrono::sys_days{std::chrono::January / 1 / 1970},
98 std::chrono::sys_days{std::chrono::March / 1 / 1970},
99 1h,
100 60min,
101 "NEXT"}},
102 R"(1970-01-01 00:00:00.001 is in a gap between
1031969-12-31 23:00:00 PREV and
1041970-01-01 01:00:00 NEXT which are both equivalent to
1051969-12-31 23:00:00 UTC)");
106
107 test(std::chrono::local_seconds{(std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},
108 std::chrono::local_info{
109 std::chrono::local_info::nonexistent,
110 std::chrono::sys_info{
111 std::chrono::sys_days{std::chrono::September / 1 / -21969},
112 std::chrono::sys_days{std::chrono::December / 31 / -21969} + 23h,
113 0s,
114 0min,
115 "PREV"},
116 std::chrono::sys_info{
117 std::chrono::sys_days{std::chrono::January / 1 / -21970},
118 std::chrono::sys_days{std::chrono::March / 1 / -21970},
119 1h,
120 60min,
121 "NEXT"}},
122 R"(-21970-01-01 00:00:00 is in a gap between
123-21969-12-31 23:00:00 PREV and
124-21970-01-01 01:00:00 NEXT which are both equivalent to
125-21969-12-31 23:00:00 UTC)");
126
127 test(
128 std::chrono::local_time<std::chrono::days>{
129 (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},
130 std::chrono::local_info{
131 std::chrono::local_info::nonexistent,
132 std::chrono::sys_info{
133 std::chrono::sys_days{std::chrono::September / 1 / 21969},
134 std::chrono::sys_days{std::chrono::December / 31 / 21969} + 23h,
135 0s,
136 0min,
137 "PREV"},
138 std::chrono::sys_info{
139 std::chrono::sys_days{std::chrono::January / 1 / 21970},
140 std::chrono::sys_days{std::chrono::March / 1 / 21970},
141 1h,
142 60min,
143 "NEXT"}},
144 R"(21970-01-01 is in a gap between
14521969-12-31 23:00:00 PREV and
14621970-01-01 01:00:00 NEXT which are both equivalent to
14721969-12-31 23:00:00 UTC)");
148
149 test(std::chrono::local_time<std::chrono::weeks>{},
150 std::chrono::local_info{
151 std::chrono::local_info::nonexistent,
152 std::chrono::sys_info{
153 std::chrono::sys_days{std::chrono::September / 1 / 1969},
154 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
155 0s,
156 0min,
157 "PREV"},
158 std::chrono::sys_info{
159 std::chrono::sys_days{std::chrono::January / 1 / 1970},
160 std::chrono::sys_days{std::chrono::March / 1 / 1970},
161 1h,
162 60min,
163 "NEXT"}},
164 R"(1970-01-01 is in a gap between
1651969-12-31 23:00:00 PREV and
1661970-01-01 01:00:00 NEXT which are both equivalent to
1671969-12-31 23:00:00 UTC)");
168
169 // Note months and years can not be streamed.
170
171 return 0;
172}
173

source code of libcxx/test/std/time/time.zone/time.zone.exception/time.zone.exception.nonexist/ctor.pass.cpp