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 ambiguous_local_time
18 //
19 // template<class Duration>
20 // ambiguous_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
28 template <class Duration>
29 static void
test(const std::chrono::local_time<Duration> & tp,const std::chrono::local_info & i,std::string_view expected)30 test(const std::chrono::local_time<Duration>& tp, const std::chrono::local_info& i, std::string_view expected) {
31 std::chrono::ambiguous_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().
main(int,char **)40 int 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 // overlap 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::ambiguous,
50 std::chrono::sys_info{
51 std::chrono::sys_days{std::chrono::January / 1 / 1970},
52 std::chrono::sys_days{std::chrono::March / 1 / 1970},
53 1h,
54 60min,
55 "PREV"},
56
57 std::chrono::sys_info{
58 std::chrono::sys_days{std::chrono::September / 1 / 1969},
59 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
60 0s,
61 0min,
62 "NEXT"}
63
64 },
65 R"(1969-12-31 23:59:59.999999999 is ambiguous. It could be
66 1969-12-31 23:59:59.999999999 PREV == 1969-12-31 22:59:59.999999999 UTC or
67 1969-12-31 23:59:59.999999999 NEXT == 1969-12-31 23:59:59.999999999 UTC)");
68
69 test(std::chrono::local_time<std::chrono::microseconds>{0us},
70 std::chrono::local_info{
71 std::chrono::local_info::ambiguous,
72 std::chrono::sys_info{
73 std::chrono::sys_days{std::chrono::January / 1 / 1970},
74 std::chrono::sys_days{std::chrono::March / 1 / 1970},
75 1h,
76 60min,
77 "PREV"},
78
79 std::chrono::sys_info{
80 std::chrono::sys_days{std::chrono::September / 1 / 1969},
81 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
82 0s,
83 0min,
84 "NEXT"}},
85 R"(1970-01-01 00:00:00.000000 is ambiguous. It could be
86 1970-01-01 00:00:00.000000 PREV == 1969-12-31 23:00:00.000000 UTC or
87 1970-01-01 00:00:00.000000 NEXT == 1970-01-01 00:00:00.000000 UTC)");
88
89 test(std::chrono::local_time<std::chrono::milliseconds>{1ms},
90 std::chrono::local_info{
91 std::chrono::local_info::ambiguous,
92 std::chrono::sys_info{
93 std::chrono::sys_days{std::chrono::January / 1 / 1970},
94 std::chrono::sys_days{std::chrono::March / 1 / 1970},
95 1h,
96 60min,
97 "PREV"},
98
99 std::chrono::sys_info{
100 std::chrono::sys_days{std::chrono::September / 1 / 1969},
101 std::chrono::sys_days{std::chrono::December / 31 / 1969} + 23h,
102 0s,
103 0min,
104 "NEXT"}},
105 R"(1970-01-01 00:00:00.001 is ambiguous. It could be
106 1970-01-01 00:00:00.001 PREV == 1969-12-31 23:00:00.001 UTC or
107 1970-01-01 00:00:00.001 NEXT == 1970-01-01 00:00:00.001 UTC)");
108
109 test(std::chrono::local_seconds{(std::chrono::sys_days{std::chrono::January / 1 / -21970}).time_since_epoch()},
110 std::chrono::local_info{
111 std::chrono::local_info::ambiguous,
112 std::chrono::sys_info{
113 std::chrono::sys_days{std::chrono::September / 1 / -21969},
114 std::chrono::sys_days{std::chrono::December / 31 / -21969},
115 0s,
116 0min,
117 "PREV"},
118 std::chrono::sys_info{
119 std::chrono::sys_days{std::chrono::January / 1 / -21970},
120 std::chrono::sys_days{std::chrono::March / 1 / -21970} + 23h,
121 1h,
122 60min,
123 "NEXT"}},
124 R"(-21970-01-01 00:00:00 is ambiguous. It could be
125 -21970-01-01 00:00:00 PREV == -21970-01-01 00:00:00 UTC or
126 -21970-01-01 00:00:00 NEXT == -21971-12-31 23:00:00 UTC)");
127
128 test(
129 std::chrono::local_time<std::chrono::days>{
130 (std::chrono::sys_days{std::chrono::January / 1 / 21970}).time_since_epoch()},
131 std::chrono::local_info{
132 std::chrono::local_info::ambiguous,
133 std::chrono::sys_info{
134 std::chrono::sys_days{std::chrono::September / 1 / 21969},
135 std::chrono::sys_days{std::chrono::December / 31 / 21969},
136 0s,
137 0min,
138 "PREV"},
139 std::chrono::sys_info{
140 std::chrono::sys_days{std::chrono::January / 1 / 21970},
141 std::chrono::sys_days{std::chrono::March / 1 / 21970} + 23h,
142 1h,
143 60min,
144 "NEXT"}},
145 R"(21970-01-01 is ambiguous. It could be
146 21970-01-01 PREV == 21970-01-01 00:00:00 UTC or
147 21970-01-01 NEXT == 21969-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::ambiguous,
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},
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} + 23h,
161 1h,
162 60min,
163 "NEXT"}},
164 R"(1970-01-01 is ambiguous. It could be
165 1970-01-01 PREV == 1970-01-01 00:00:00 UTC or
166 1970-01-01 NEXT == 1969-12-31 23:00:00 UTC)");
167
168 // Note months and years can not be streamed.
169
170 return 0;
171 }
172