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 utc_clock;
18
19// template<class Duration>
20// static utc_time<common_type_t<Duration, seconds>>
21// from_sys(const sys_time<Duration>& time);
22
23#include <chrono>
24#include <cassert>
25
26#include "test_macros.h"
27#include "assert_macros.h"
28#include "concat_macros.h"
29
30template <class Duration>
31static void test_leap_seconds(std::chrono::time_point<std::chrono::system_clock, Duration> time,
32 std::chrono::seconds leap_seconds) {
33 auto utc = std::chrono::utc_clock::from_sys(time);
34 auto diff = utc.time_since_epoch() - time.time_since_epoch();
35 TEST_REQUIRE(
36 diff == leap_seconds,
37 TEST_WRITE_CONCATENATED("\tTime: ", time, "\nExpected output ", leap_seconds, "\nActual output ", diff, '\n'));
38}
39
40// This test is based on the example in [time.clock.utc.members]/3
41static void test_example_standard() {
42 using namespace std::literals::chrono_literals;
43
44 auto t = std::chrono::sys_days{std::chrono::July / 1 / 2015} - 2ns;
45 test_leap_seconds(t, 25s);
46
47 t += 1ns;
48 test_leap_seconds(t, 25s);
49
50 t += 1ns;
51 test_leap_seconds(t, 26s);
52
53 t += 1ns;
54 test_leap_seconds(t, 26s);
55}
56
57// Tests set of existing database entries at the time of writing.
58static void test_transitions() {
59 using namespace std::literals::chrono_literals;
60
61 test_leap_seconds(std::chrono::sys_seconds::min(), 0s);
62 test_leap_seconds(std::chrono::sys_days::min(), 0s);
63
64 // Epoch transition no transitions.
65 test_leap_seconds(std::chrono::sys_seconds{-1s}, 0s);
66 test_leap_seconds(std::chrono::sys_seconds{0s}, 0s);
67 test_leap_seconds(std::chrono::sys_seconds{1s}, 0s);
68
69 // Transitions from the start of UTC.
70 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1972} - 1ns, 0s);
71 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1972}, 0s);
72 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1972} + 1ns, 0s);
73
74 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1972} - 1ns, 0s);
75 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1972}, 1s);
76 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1972} + 1ns, 1s);
77
78 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1973} - 1ns, 1s);
79 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1973}, 2s);
80 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1973} + 1ns, 2s);
81
82 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1974} - 1ns, 2s);
83 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1974}, 3s);
84 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1974} + 1ns, 3s);
85
86 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1975} - 1ns, 3s);
87 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1975}, 4s);
88 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1975} + 1ns, 4s);
89
90 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1976} - 1ns, 4s);
91 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1976}, 5s);
92 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1976} + 1ns, 5s);
93
94 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1977} - 1ns, 5s);
95 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1977}, 6s);
96 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1977} + 1ns, 6s);
97
98 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1978} - 1ns, 6s);
99 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1978}, 7s);
100 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1978} + 1ns, 7s);
101
102 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1979} - 1ns, 7s);
103 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1979}, 8s);
104 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1979} + 1ns, 8s);
105
106 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1980} - 1ns, 8s);
107 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1980}, 9s);
108 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1980} + 1ns, 9s);
109
110 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1981} - 1ns, 9s);
111 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1981}, 10s);
112 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1981} + 1ns, 10s);
113
114 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1982} - 1ns, 10s);
115 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1982}, 11s);
116 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1982} + 1ns, 11s);
117
118 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1983} - 1ns, 11s);
119 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1983}, 12s);
120 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1983} + 1ns, 12s);
121
122 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1985} - 1ns, 12s);
123 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1985}, 13s);
124 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1985} + 1ns, 13s);
125
126 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1988} - 1ns, 13s);
127 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1988}, 14s);
128 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1988} + 1ns, 14s);
129
130 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1990} - 1ns, 14s);
131 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1990}, 15s);
132 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1990} + 1ns, 15s);
133
134 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1991} - 1ns, 15s);
135 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1991}, 16s);
136 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1991} + 1ns, 16s);
137
138 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1992} - 1ns, 16s);
139 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1992}, 17s);
140 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1992} + 1ns, 17s);
141
142 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1993} - 1ns, 17s);
143 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1993}, 18s);
144 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1993} + 1ns, 18s);
145
146 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1994} - 1ns, 18s);
147 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1994}, 19s);
148 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1994} + 1ns, 19s);
149
150 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1996} - 1ns, 19s);
151 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1996}, 20s);
152 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1996} + 1ns, 20s);
153
154 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1997} - 1ns, 20s);
155 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1997}, 21s);
156 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 1997} + 1ns, 21s);
157
158 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1999} - 1ns, 21s);
159 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1999}, 22s);
160 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 1999} + 1ns, 22s);
161
162 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2006} - 1ns, 22s);
163 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2006}, 23s);
164 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2006} + 1ns, 23s);
165
166 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2009} - 1ns, 23s);
167 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2009}, 24s);
168 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2009} + 1ns, 24s);
169
170 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2012} - 1ns, 24s);
171 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2012}, 25s);
172 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2012} + 1ns, 25s);
173
174 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2015} - 1ns, 25s);
175 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2015}, 26s);
176 test_leap_seconds(std::chrono::sys_days{std::chrono::July / 1 / 2015} + 1ns, 26s);
177
178 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2017} - 1ns, 26s);
179 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2017}, 27s);
180 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2017} + 1ns, 27s);
181
182 // This validates status when the tests were written.
183 // It's not possible to test the future; there might be additional leap
184 // seconds in the future.
185 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2024} - 1ns, 27s);
186 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2024}, 27s);
187 test_leap_seconds(std::chrono::sys_days{std::chrono::January / 1 / 2024} + 1ns, 27s);
188}
189
190// Tests whether the return type is the expected type.
191static void test_return_type() {
192 namespace cr = std::chrono;
193 using namespace std::literals::chrono_literals;
194
195 {
196 [[maybe_unused]] std::same_as<cr::utc_time<cr::nanoseconds>> decltype(auto) _ =
197 cr::utc_clock::from_sys(cr::sys_time<cr::nanoseconds>{0ns});
198 }
199 {
200 [[maybe_unused]] std::same_as<cr::utc_time<cr::microseconds>> decltype(auto) _ =
201 cr::utc_clock::from_sys(cr::sys_time<cr::microseconds>{0us});
202 }
203 {
204 [[maybe_unused]] std::same_as<cr::utc_time<cr::milliseconds>> decltype(auto) _ =
205 cr::utc_clock::from_sys(cr::sys_time<cr::milliseconds>{0ms});
206 }
207
208 {
209 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
210 cr::utc_clock::from_sys(cr::sys_time<cr::seconds>{cr::seconds{0}});
211 }
212
213 {
214 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
215 cr::utc_clock::from_sys(cr::sys_time<cr::minutes>{cr::minutes{0}});
216 }
217 {
218 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
219 cr::utc_clock::from_sys(cr::sys_time<cr::hours>{cr::hours{0}});
220 }
221 {
222 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
223 cr::utc_clock::from_sys(cr::sys_time<cr::days>{cr::days{0}});
224 }
225 {
226 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
227 cr::utc_clock::from_sys(cr::sys_time<cr::weeks>{cr::weeks{0}});
228 }
229 {
230 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
231 cr::utc_clock::from_sys(cr::sys_time<cr::months>{cr::months{0}});
232 }
233 {
234 [[maybe_unused]] std::same_as<cr::utc_time<cr::seconds>> decltype(auto) _ =
235 cr::utc_clock::from_sys(cr::sys_time<cr::years>{cr::years{0}});
236 }
237}
238
239int main(int, const char**) {
240 test_example_standard();
241 test_transitions();
242 test_return_type();
243
244 return 0;
245}
246

source code of libcxx/test/std/time/time.clock/time.clock.utc/time.clock.utc.members/from_sys.pass.cpp