1 //===----------------------------------------------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 // UNSUPPORTED: c++03, c++11, c++14, c++17
9 // UNSUPPORTED: no-localization
10 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
11
12 // TODO FMT This test should not require std::to_chars(floating-point)
13 // XFAIL: availability-fp_to_chars-missing
14
15 // REQUIRES: locale.fr_FR.UTF-8
16 // REQUIRES: locale.ja_JP.UTF-8
17
18 // <chrono>
19 //
20 // template<class charT> struct formatter<chrono::day, charT>;
21
22 #include <chrono>
23 #include <format>
24
25 #include <cassert>
26 #include <concepts>
27 #include <locale>
28 #include <iostream>
29 #include <type_traits>
30
31 #include "formatter_tests.h"
32 #include "make_string.h"
33 #include "platform_support.h" // locale name macros
34 #include "test_macros.h"
35
36 template <class CharT>
test_no_chrono_specs()37 static void test_no_chrono_specs() {
38 using namespace std::literals::chrono_literals;
39
40 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
41
42 // Non localized output
43
44 // [time.syn]
45 // using nanoseconds = duration<signed integer type of at least 64 bits, nano>;
46 // using microseconds = duration<signed integer type of at least 55 bits, micro>;
47 // using milliseconds = duration<signed integer type of at least 45 bits, milli>;
48 // using seconds = duration<signed integer type of at least 35 bits>;
49 // using minutes = duration<signed integer type of at least 29 bits, ratio< 60>>;
50 // using hours = duration<signed integer type of at least 23 bits, ratio<3600>>;
51 check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::sys_seconds(-17'179'869'184s)); // Minimum value for 35 bits.
52 check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::sys_seconds(-2'147'483'648s));
53
54 check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::sys_seconds(-24h));
55 check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::sys_seconds(-18h));
56 check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::sys_seconds(-12h));
57 check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::sys_seconds(-6h));
58 check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::sys_seconds(-1s));
59
60 check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(0s));
61 check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(946'684'800s));
62 check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::sys_seconds(946'688'523s));
63
64 check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::sys_seconds(2'147'483'647s));
65 check(SV("2514-05-30 01:53:03"), SV("{}"), std::chrono::sys_seconds(17'179'869'183s)); // Maximum value for 35 bits.
66
67 check(SV("2000-01-01 01:02:03.123"), SV("{}"), std::chrono::sys_time<std::chrono::milliseconds>(946'688'523'123ms));
68
69 std::locale::global(std::locale::classic());
70 }
71
72 template <class CharT>
test_valid_values_year()73 static void test_valid_values_year() {
74 using namespace std::literals::chrono_literals;
75
76 constexpr std::basic_string_view<CharT> fmt =
77 SV("{:%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");
78 constexpr std::basic_string_view<CharT> lfmt =
79 SV("{:L%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");
80
81 const std::locale loc(LOCALE_ja_JP_UTF_8);
82 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
83
84 // Non localized output using C-locale
85 check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
86 fmt,
87 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
88
89 check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
90 fmt,
91 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
92
93 // Use the global locale (fr_FR)
94 check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
95 lfmt,
96 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
97
98 check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
99 lfmt,
100 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
101
102 // Use supplied locale (ja_JP). This locale has a different alternate.
103 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
104 check(loc,
105 SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
106 lfmt,
107 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
108
109 check(loc,
110 SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
111 lfmt,
112 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
113 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)
114 check(loc,
115 SV("%C='19'\t%EC='昭和'\t%y='70'\t%Oy='七十'\t%Ey='45'\t%Y='1970'\t%EY='昭和45年'\n"),
116 lfmt,
117 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
118
119 check(loc,
120 SV("%C='20'\t%EC='平成'\t%y='09'\t%Oy='九'\t%Ey='21'\t%Y='2009'\t%EY='平成21年'\n"),
121 lfmt,
122 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
123 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)
124
125 std::locale::global(std::locale::classic());
126 }
127
128 template <class CharT>
test_valid_values_month()129 static void test_valid_values_month() {
130 using namespace std::literals::chrono_literals;
131
132 constexpr std::basic_string_view<CharT> fmt = SV("{:%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");
133 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");
134
135 const std::locale loc(LOCALE_ja_JP_UTF_8);
136 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
137
138 // Non localized output using C-locale
139 check(SV("%b='Jan'\t%h='Jan'\t%B='January'\t%m='01'\t%Om='01'\n"),
140 fmt,
141 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
142
143 check(SV("%b='May'\t%h='May'\t%B='May'\t%m='05'\t%Om='05'\n"),
144 fmt,
145 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
146
147 // Use the global locale (fr_FR)
148 #if defined(__APPLE__)
149 check(SV("%b='jan'\t%h='jan'\t%B='janvier'\t%m='01'\t%Om='01'\n"),
150 lfmt,
151 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
152 #else
153 check(SV("%b='janv.'\t%h='janv.'\t%B='janvier'\t%m='01'\t%Om='01'\n"),
154 lfmt,
155 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
156 #endif
157
158 check(SV("%b='mai'\t%h='mai'\t%B='mai'\t%m='05'\t%Om='05'\n"),
159 lfmt,
160 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
161
162 // Use supplied locale (ja_JP). This locale has a different alternate.
163 #ifdef _WIN32
164 check(loc,
165 SV("%b='1'\t%h='1'\t%B='1月'\t%m='01'\t%Om='01'\n"),
166 lfmt,
167 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
168
169 check(loc,
170 SV("%b='5'\t%h='5'\t%B='5月'\t%m='05'\t%Om='05'\n"),
171 lfmt,
172 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
173 #elif defined(_AIX) // _WIN32
174 check(loc,
175 SV("%b='1月'\t%h='1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),
176 lfmt,
177 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
178
179 check(loc,
180 SV("%b='5月'\t%h='5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),
181 lfmt,
182 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
183 #elif defined(__APPLE__) // _WIN32
184 check(loc,
185 SV("%b=' 1'\t%h=' 1'\t%B='1月'\t%m='01'\t%Om='01'\n"),
186 lfmt,
187 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
188
189 check(loc,
190 SV("%b=' 5'\t%h=' 5'\t%B='5月'\t%m='05'\t%Om='05'\n"),
191 lfmt,
192 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
193 #elif defined(__FreeBSD__) // _WIN32
194 check(loc,
195 SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),
196 lfmt,
197 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
198
199 check(loc,
200 SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),
201 lfmt,
202 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
203 #else // _WIN32
204 check(loc,
205 SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='一'\n"),
206 lfmt,
207 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
208
209 check(loc,
210 SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='五'\n"),
211 lfmt,
212 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
213 #endif // _WIN32
214
215 std::locale::global(std::locale::classic());
216 }
217
218 template <class CharT>
test_valid_values_day()219 static void test_valid_values_day() {
220 using namespace std::literals::chrono_literals;
221
222 constexpr std::basic_string_view<CharT> fmt = SV("{:%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");
223 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");
224
225 const std::locale loc(LOCALE_ja_JP_UTF_8);
226 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
227
228 // Non localized output using C-locale
229 check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
230 fmt,
231 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
232
233 check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
234 fmt,
235 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
236
237 // Use the global locale (fr_FR)
238 check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
239 lfmt,
240 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
241
242 check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
243 lfmt,
244 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
245
246 // Use supplied locale (ja_JP). This locale has a different alternate.
247 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
248 check(loc,
249 SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
250 lfmt,
251 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
252
253 check(loc,
254 SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
255 lfmt,
256 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
257 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
258 check(loc,
259 SV("%d='01'\t%Od='一'\t%e=' 1'\t%Oe='一'\n"),
260 lfmt,
261 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
262
263 check(loc,
264 SV("%d='13'\t%Od='十三'\t%e='13'\t%Oe='十三'\n"),
265 lfmt,
266 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
267
268 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
269
270 std::locale::global(std::locale::classic());
271 }
272
273 template <class CharT>
test_valid_values_weekday()274 static void test_valid_values_weekday() {
275 using namespace std::literals::chrono_literals;
276
277 constexpr std::basic_string_view<CharT> fmt =
278 SV("{:%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
279 constexpr std::basic_string_view<CharT> lfmt =
280 SV("{:L%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
281
282 const std::locale loc(LOCALE_ja_JP_UTF_8);
283 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
284
285 // Non localized output using C-locale
286 check(SV("%a='Thu'\t%A='Thursday'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
287 fmt,
288 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
289
290 check(SV("%a='Sun'\t%A='Sunday'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
291 fmt,
292 std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
293
294 // Use the global locale (fr_FR)
295 #if defined(__APPLE__)
296 check(SV("%a='Jeu'\t%A='Jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
297 lfmt,
298 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
299
300 check(SV("%a='Dim'\t%A='Dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
301 lfmt,
302 std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
303 #else
304 check(SV("%a='jeu.'\t%A='jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
305 lfmt,
306 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
307
308 check(SV("%a='dim.'\t%A='dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
309 lfmt,
310 std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
311 #endif
312
313 // Use supplied locale (ja_JP).
314 // This locale has a different alternate, but not on all platforms
315 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
316 check(loc,
317 SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
318 lfmt,
319 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
320
321 check(loc,
322 SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
323 lfmt,
324 std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
325 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
326 check(loc,
327 SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\n"),
328 lfmt,
329 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
330
331 check(loc,
332 SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\n"),
333 lfmt,
334 std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
335 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
336
337 std::locale::global(std::locale::classic());
338 }
339
340 template <class CharT>
test_valid_values_day_of_year()341 static void test_valid_values_day_of_year() {
342 using namespace std::literals::chrono_literals;
343
344 constexpr std::basic_string_view<CharT> fmt = SV("{:%%j='%j'%n}");
345 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%j='%j'%n}");
346
347 const std::locale loc(LOCALE_ja_JP_UTF_8);
348 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
349
350 // Non localized output using C-locale
351 check(SV("%j='001'\n"), fmt, std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
352 check(SV("%j='138'\n"), fmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
353
354 // Use the global locale (fr_FR)
355 check(SV("%j='001'\n"), lfmt, std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
356 check(SV("%j='138'\n"), lfmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
357
358 // Use supplied locale (ja_JP). This locale has a different alternate.
359 check(loc, SV("%j='001'\n"), lfmt, std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
360
361 check(
362 loc, SV("%j='138'\n"), lfmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
363
364 std::locale::global(std::locale::classic());
365 }
366
367 template <class CharT>
test_valid_values_week()368 static void test_valid_values_week() {
369 using namespace std::literals::chrono_literals;
370
371 constexpr std::basic_string_view<CharT> fmt = SV("{:%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");
372 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");
373
374 const std::locale loc(LOCALE_ja_JP_UTF_8);
375 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
376
377 // Non localized output using C-locale
378 check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
379 fmt,
380 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
381
382 check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
383 fmt,
384 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
385
386 // Use the global locale (fr_FR)
387 check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
388 lfmt,
389 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
390
391 check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
392 lfmt,
393 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
394
395 // Use supplied locale (ja_JP). This locale has a different alternate.
396 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
397 check(loc,
398 SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
399 lfmt,
400 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
401
402 check(loc,
403 SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
404 lfmt,
405 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
406 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
407 check(loc,
408 SV("%U='00'\t%OU='〇'\t%W='00'\t%OW='〇'\n"),
409 lfmt,
410 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
411
412 check(loc,
413 SV("%U='20'\t%OU='二十'\t%W='20'\t%OW='二十'\n"),
414 lfmt,
415 std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
416 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
417 std::locale::global(std::locale::classic());
418 }
419
420 template <class CharT>
test_valid_values_iso_8601_week()421 static void test_valid_values_iso_8601_week() {
422 using namespace std::literals::chrono_literals;
423
424 constexpr std::basic_string_view<CharT> fmt = SV("{:%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");
425 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");
426
427 const std::locale loc(LOCALE_ja_JP_UTF_8);
428 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
429
430 // Non localized output using C-locale
431 check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
432 fmt,
433 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
434
435 check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
436 fmt,
437 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
438
439 // Use the global locale (fr_FR)
440 check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
441 lfmt,
442 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
443
444 check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
445 lfmt,
446 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
447
448 // Use supplied locale (ja_JP). This locale has a different alternate.
449 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
450 check(loc,
451 SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
452 lfmt,
453 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
454
455 check(loc,
456 SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
457 lfmt,
458 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
459 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
460 check(loc,
461 SV("%g='70'\t%G='1970'\t%V='01'\t%OV='一'\n"),
462 lfmt,
463 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
464
465 check(loc,
466 SV("%g='09'\t%G='2009'\t%V='07'\t%OV='七'\n"),
467 lfmt,
468 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
469 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
470
471 std::locale::global(std::locale::classic());
472 }
473
474 template <class CharT>
test_valid_values_date()475 static void test_valid_values_date() {
476 using namespace std::literals::chrono_literals;
477
478 constexpr std::basic_string_view<CharT> fmt = SV("{:%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");
479 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");
480
481 const std::locale loc(LOCALE_ja_JP_UTF_8);
482 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
483
484 // Non localized output using C-locale
485 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/70'\t%Ex='01/01/70'\n"),
486 fmt,
487 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
488
489 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='02/13/09'\t%Ex='02/13/09'\n"),
490 fmt,
491 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
492
493 // Use the global locale (fr_FR)
494 #if defined(__APPLE__) || defined(__FreeBSD__)
495 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01.01.1970'\t%Ex='01.01.1970'\n"),
496 lfmt,
497 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
498
499 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13.02.2009'\t%Ex='13.02.2009'\n"),
500 lfmt,
501 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
502 #else
503 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/1970'\t%Ex='01/01/1970'\n"),
504 lfmt,
505 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
506
507 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13/02/2009'\t%Ex='13/02/2009'\n"),
508 lfmt,
509 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
510 #endif
511
512 // Use supplied locale (ja_JP). This locale has a different alternate.
513 #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
514 check(loc,
515 SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970/01/01'\t%Ex='1970/01/01'\n"),
516 lfmt,
517 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
518
519 check(loc,
520 SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009/02/13'\t%Ex='2009/02/13'\n"),
521 lfmt,
522 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
523 #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
524 check(loc,
525 SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970年01月01日'\t%Ex='昭和45年01月01日'\n"),
526 lfmt,
527 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
528
529 check(loc,
530 SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009年02月13日'\t%Ex='平成21年02月13日'\n"),
531 lfmt,
532 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
533 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
534
535 std::locale::global(std::locale::classic());
536 }
537
538 template <class CharT>
test_valid_values_time()539 static void test_valid_values_time() {
540 using namespace std::literals::chrono_literals;
541
542 constexpr std::basic_string_view<CharT> fmt = SV(
543 "{:"
544 "%%H='%H'%t"
545 "%%OH='%OH'%t"
546 "%%I='%I'%t"
547 "%%OI='%OI'%t"
548 "%%M='%M'%t"
549 "%%OM='%OM'%t"
550 "%%S='%S'%t"
551 "%%OS='%OS'%t"
552 "%%p='%p'%t"
553 "%%R='%R'%t"
554 "%%T='%T'%t"
555 "%%r='%r'%t"
556 "%%X='%X'%t"
557 "%%EX='%EX'%t"
558 "%n}");
559 constexpr std::basic_string_view<CharT> lfmt = SV(
560 "{:L"
561 "%%H='%H'%t"
562 "%%OH='%OH'%t"
563 "%%I='%I'%t"
564 "%%OI='%OI'%t"
565 "%%M='%M'%t"
566 "%%OM='%OM'%t"
567 "%%S='%S'%t"
568 "%%OS='%OS'%t"
569 "%%p='%p'%t"
570 "%%R='%R'%t"
571 "%%T='%T'%t"
572 "%%r='%r'%t"
573 "%%X='%X'%t"
574 "%%EX='%EX'%t"
575 "%n}");
576
577 const std::locale loc(LOCALE_ja_JP_UTF_8);
578 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
579
580 // Non localized output using C-locale
581 check(SV("%H='00'\t"
582 "%OH='00'\t"
583 "%I='12'\t"
584 "%OI='12'\t"
585 "%M='00'\t"
586 "%OM='00'\t"
587 "%S='00'\t"
588 "%OS='00'\t"
589 "%p='AM'\t"
590 "%R='00:00'\t"
591 "%T='00:00:00'\t"
592 "%r='12:00:00 AM'\t"
593 "%X='00:00:00'\t"
594 "%EX='00:00:00'\t"
595 "\n"),
596 fmt,
597 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
598
599 check(SV("%H='23'\t"
600 "%OH='23'\t"
601 "%I='11'\t"
602 "%OI='11'\t"
603 "%M='31'\t"
604 "%OM='31'\t"
605 "%S='30.123'\t"
606 "%OS='30.123'\t"
607 "%p='PM'\t"
608 "%R='23:31'\t"
609 "%T='23:31:30.123'\t"
610 "%r='11:31:30 PM'\t"
611 "%X='23:31:30'\t"
612 "%EX='23:31:30'\t"
613 "\n"),
614 fmt,
615 std::chrono::sys_time<std::chrono::milliseconds>(
616 1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
617 // Use the global locale (fr_FR)
618 check(SV("%H='00'\t"
619 "%OH='00'\t"
620 "%I='12'\t"
621 "%OI='12'\t"
622 "%M='00'\t"
623 "%OM='00'\t"
624 "%S='00'\t"
625 "%OS='00'\t"
626 #if defined(_AIX)
627 "%p='AM'\t"
628 #else
629 "%p=''\t"
630 #endif
631 "%R='00:00'\t"
632 "%T='00:00:00'\t"
633 #ifdef _WIN32
634 "%r='00:00:00'\t"
635 #elif defined(_AIX)
636 "%r='12:00:00 AM'\t"
637 #elif defined(__APPLE__) || defined(__FreeBSD__)
638 "%r=''\t"
639 #else
640 "%r='12:00:00 '\t"
641 #endif
642 "%X='00:00:00'\t"
643 "%EX='00:00:00'\t"
644 "\n"),
645 lfmt,
646 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
647
648 check(SV("%H='23'\t"
649 "%OH='23'\t"
650 "%I='11'\t"
651 "%OI='11'\t"
652 "%M='31'\t"
653 "%OM='31'\t"
654 "%S='30,123'\t"
655 "%OS='30,123'\t"
656 #if defined(_AIX)
657 "%p='PM'\t"
658 #else
659 "%p=''\t"
660 #endif
661 "%R='23:31'\t"
662 "%T='23:31:30,123'\t"
663 #ifdef _WIN32
664 "%r='23:31:30'\t"
665 #elif defined(_AIX)
666 "%r='11:31:30 PM'\t"
667 #elif defined(__APPLE__) || defined(__FreeBSD__)
668 "%r=''\t"
669 #else
670 "%r='11:31:30 '\t"
671 #endif
672 "%X='23:31:30'\t"
673 "%EX='23:31:30'\t"
674 "\n"),
675 lfmt,
676 std::chrono::sys_time<std::chrono::milliseconds>(
677 1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
678
679 // Use supplied locale (ja_JP). This locale has a different alternate.
680 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
681 check(loc,
682 SV("%H='00'\t"
683 "%OH='00'\t"
684 "%I='12'\t"
685 "%OI='12'\t"
686 "%M='00'\t"
687 "%OM='00'\t"
688 "%S='00'\t"
689 "%OS='00'\t"
690 # if defined(__APPLE__)
691 "%p='AM'\t"
692 # else
693 "%p='午前'\t"
694 # endif
695 "%R='00:00'\t"
696 "%T='00:00:00'\t"
697 # if defined(__APPLE__) || defined(__FreeBSD__)
698 # if defined(__APPLE__)
699 "%r='12:00:00 AM'\t"
700 # else
701 "%r='12:00:00 午前'\t"
702 # endif
703 "%X='00時00分00秒'\t"
704 "%EX='00時00分00秒'\t"
705 # elif defined(_WIN32)
706 "%r='0:00:00'\t"
707 "%X='0:00:00'\t"
708 "%EX='0:00:00'\t"
709 # else
710 "%r='午前12:00:00'\t"
711 "%X='00:00:00'\t"
712 "%EX='00:00:00'\t"
713 # endif
714 "\n"),
715 lfmt,
716 std::chrono::hh_mm_ss(0s));
717
718 check(loc,
719 SV("%H='23'\t"
720 "%OH='23'\t"
721 "%I='11'\t"
722 "%OI='11'\t"
723 "%M='31'\t"
724 "%OM='31'\t"
725 "%S='30.123'\t"
726 "%OS='30.123'\t"
727 # if defined(__APPLE__)
728 "%p='PM'\t"
729 # else
730 "%p='午後'\t"
731 # endif
732 "%R='23:31'\t"
733 "%T='23:31:30.123'\t"
734 # if defined(__APPLE__) || defined(__FreeBSD__)
735 # if defined(__APPLE__)
736 "%r='11:31:30 PM'\t"
737 # else
738 "%r='11:31:30 午後'\t"
739 # endif
740 "%X='23時31分30秒'\t"
741 "%EX='23時31分30秒'\t"
742 # elif defined(_WIN32)
743 "%r='23:31:30'\t"
744 "%X='23:31:30'\t"
745 "%EX='23:31:30'\t"
746 # else
747 "%r='午後11:31:30'\t"
748 "%X='23:31:30'\t"
749 "%EX='23:31:30'\t"
750 # endif
751 "\n"),
752 lfmt,
753 std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));
754 #else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
755 check(loc,
756 SV("%H='00'\t"
757 "%OH='〇'\t"
758 "%I='12'\t"
759 "%OI='十二'\t"
760 "%M='00'\t"
761 "%OM='〇'\t"
762 "%S='00'\t"
763 "%OS='〇'\t"
764 "%p='午前'\t"
765 "%R='00:00'\t"
766 "%T='00:00:00'\t"
767 "%r='午前12時00分00秒'\t"
768 "%X='00時00分00秒'\t"
769 "%EX='00時00分00秒'\t"
770 "\n"),
771 lfmt,
772 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
773
774 check(loc,
775 SV("%H='23'\t"
776 "%OH='二十三'\t"
777 "%I='11'\t"
778 "%OI='十一'\t"
779 "%M='31'\t"
780 "%OM='三十一'\t"
781 "%S='30.123'\t"
782 "%OS='三十.123'\t"
783 "%p='午後'\t"
784 "%R='23:31'\t"
785 "%T='23:31:30.123'\t"
786 "%r='午後11時31分30秒'\t"
787 "%X='23時31分30秒'\t"
788 "%EX='23時31分30秒'\t"
789 "\n"),
790 lfmt,
791 std::chrono::sys_time<std::chrono::milliseconds>(
792 1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
793 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
794
795 std::locale::global(std::locale::classic());
796 }
797
798 template <class CharT>
test_valid_values_date_time()799 static void test_valid_values_date_time() {
800 using namespace std::literals::chrono_literals;
801
802 constexpr std::basic_string_view<CharT> fmt = SV("{:%%c='%c'%t%%Ec='%Ec'%n}");
803 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%c='%c'%t%%Ec='%Ec'%n}");
804
805 const std::locale loc(LOCALE_ja_JP_UTF_8);
806 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
807
808 // Non localized output using C-locale
809 check(SV("%c='Thu Jan 1 00:00:00 1970'\t%Ec='Thu Jan 1 00:00:00 1970'\n"),
810 fmt,
811 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
812
813 check(SV("%c='Fri Feb 13 23:31:30 2009'\t%Ec='Fri Feb 13 23:31:30 2009'\n"),
814 fmt,
815 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
816
817 // Use the global locale (fr_FR)
818 check(
819 // https://sourceware.org/bugzilla/show_bug.cgi?id=24054
820 #if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
821 SV("%c='jeu. 01 janv. 1970 00:00:00 GMT'\t%Ec='jeu. 01 janv. 1970 00:00:00 GMT'\n"),
822 #elif defined(_AIX)
823 SV("%c=' 1 janvier 1970 à 00:00:00 UTC'\t%Ec=' 1 janvier 1970 à 00:00:00 UTC'\n"),
824 #elif defined(__APPLE__)
825 SV("%c='Jeu 1 jan 00:00:00 1970'\t%Ec='Jeu 1 jan 00:00:00 1970'\n"),
826 #elif defined(_WIN32)
827 SV("%c='01/01/1970 00:00:00'\t%Ec='01/01/1970 00:00:00'\n"),
828 #elif defined(__FreeBSD__)
829 SV("%c='jeu. 1 janv. 00:00:00 1970'\t%Ec='jeu. 1 janv. 00:00:00 1970'\n"),
830 #else
831 SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"),
832 #endif
833 lfmt,
834 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
835
836 check(
837 // https://sourceware.org/bugzilla/show_bug.cgi?id=24054
838 #if defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
839 SV("%c='ven. 13 févr. 2009 23:31:30 GMT'\t%Ec='ven. 13 févr. 2009 23:31:30 GMT'\n"),
840 #elif defined(_AIX)
841 SV("%c='13 février 2009 à 23:31:30 UTC'\t%Ec='13 février 2009 à 23:31:30 UTC'\n"),
842 #elif defined(__APPLE__)
843 SV("%c='Ven 13 fév 23:31:30 2009'\t%Ec='Ven 13 fév 23:31:30 2009'\n"),
844 #elif defined(_WIN32)
845 SV("%c='13/02/2009 23:31:30'\t%Ec='13/02/2009 23:31:30'\n"),
846 #elif defined(__FreeBSD__)
847 SV("%c='ven. 13 févr. 23:31:30 2009'\t%Ec='ven. 13 févr. 23:31:30 2009'\n"),
848 #else
849 SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"),
850 #endif
851 lfmt,
852 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
853
854 // Use supplied locale (ja_JP). This locale has a different alternate.a
855 #if defined(__APPLE__) || defined(__FreeBSD__)
856 check(loc,
857 SV("%c='木 1/ 1 00:00:00 1970'\t%Ec='木 1/ 1 00:00:00 1970'\n"),
858 lfmt,
859 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
860 check(loc,
861 SV("%c='金 2/13 23:31:30 2009'\t%Ec='金 2/13 23:31:30 2009'\n"),
862 lfmt,
863 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
864 #elif defined(_AIX) // defined(__APPLE__)|| defined(__FreeBSD__)
865 check(loc,
866 SV("%c='1970年01月 1日 00:00:00 UTC'\t%Ec='1970年01月 1日 00:00:00 UTC'\n"),
867 lfmt,
868 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
869 check(loc,
870 SV("%c='2009年02月13日 23:31:30 UTC'\t%Ec='2009年02月13日 23:31:30 UTC'\n"),
871 lfmt,
872 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
873 #elif defined(_WIN32) // defined(__APPLE__)|| defined(__FreeBSD__)
874 check(loc,
875 SV("%c='1970/01/01 0:00:00'\t%Ec='1970/01/01 0:00:00'\n"),
876 lfmt,
877 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
878 check(loc,
879 SV("%c='2009/02/13 23:31:30'\t%Ec='2009/02/13 23:31:30'\n"),
880 lfmt,
881 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
882 #else // defined(__APPLE__)|| defined(__FreeBSD__)
883 check(loc,
884 SV("%c='1970年01月01日 00時00分00秒'\t%Ec='昭和45年01月01日 00時00分00秒'\n"),
885 lfmt,
886 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
887
888 check(loc,
889 SV("%c='2009年02月13日 23時31分30秒'\t%Ec='平成21年02月13日 23時31分30秒'\n"),
890 lfmt,
891 std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
892 #endif // defined(__APPLE__)|| defined(__FreeBSD__)
893
894 std::locale::global(std::locale::classic());
895 }
896
897 template <class CharT>
test_valid_values_time_zone()898 static void test_valid_values_time_zone() {
899 // The Apple CI gives %z='-0700' %Ez='-0700' %Oz='-0700' %Z='UTC'
900 // -0700 looks like the local time where the CI happens to reside, therefore
901 // omit this test on Apple.
902 // The Windows CI gives %z='-0000', but on local machines set to a different
903 // timezone, it gives e.g. %z='+0200'.
904 #if !defined(__APPLE__) && !defined(_WIN32)
905 using namespace std::literals::chrono_literals;
906
907 constexpr std::basic_string_view<CharT> fmt = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
908 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
909
910 const std::locale loc(LOCALE_ja_JP_UTF_8);
911 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
912
913 # if defined(_AIX)
914 // Non localized output using C-locale
915 check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
916 fmt,
917 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
918
919 // Use the global locale (fr_FR)
920 check(SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
921 lfmt,
922 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
923
924 // Use supplied locale (ja_JP). This locale has a different alternate.a
925 check(loc,
926 SV("%z='UTC'\t%Ez='UTC'\t%Oz='UTC'\t%Z='UTC'\n"),
927 lfmt,
928 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
929 # else // defined(_AIX)
930 // Non localized output using C-locale
931 check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
932 fmt,
933 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
934
935 // Use the global locale (fr_FR)
936 check(SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
937 lfmt,
938 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
939
940 // Use supplied locale (ja_JP). This locale has a different alternate.a
941 # if defined(__FreeBSD__)
942 check(loc,
943 SV("%z='+0000'\t%Ez='+0000'\t%Oz='+0000'\t%Z='UTC'\n"),
944 lfmt,
945 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
946 # else
947 check(loc,
948 SV("%z='+0000'\t%Ez='+0000'\t%Oz='+〇'\t%Z='UTC'\n"),
949 lfmt,
950 std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
951 # endif
952 # endif // defined(_AIX)
953 std::locale::global(std::locale::classic());
954 #endif // !defined(__APPLE__) && !defined(_WIN32)
955 }
956
957 template <class CharT>
test_valid_values()958 static void test_valid_values() {
959 test_valid_values_year<CharT>();
960 test_valid_values_month<CharT>();
961 test_valid_values_day<CharT>();
962 test_valid_values_weekday<CharT>();
963 test_valid_values_day_of_year<CharT>();
964 test_valid_values_week<CharT>();
965 test_valid_values_iso_8601_week<CharT>();
966 test_valid_values_date<CharT>();
967 test_valid_values_time<CharT>();
968 test_valid_values_date_time<CharT>();
969 test_valid_values_time_zone<CharT>();
970 }
971
972 template <class CharT>
test()973 static void test() {
974 using namespace std::literals::chrono_literals;
975
976 test_no_chrono_specs<CharT>();
977 test_valid_values<CharT>();
978 check_invalid_types<CharT>(
979 {SV("a"), SV("A"), SV("b"), SV("B"), SV("c"), SV("C"), SV("d"), SV("D"), SV("e"), SV("F"), SV("g"),
980 SV("G"), SV("h"), SV("H"), SV("I"), SV("j"), SV("m"), SV("M"), SV("p"), SV("r"), SV("R"), SV("S"),
981 SV("T"), SV("u"), SV("U"), SV("V"), SV("w"), SV("W"), SV("x"), SV("X"), SV("y"), SV("Y"), SV("z"),
982 SV("Z"), SV("Ec"), SV("EC"), SV("Ex"), SV("EX"), SV("Ey"), SV("EY"), SV("Ez"), SV("Od"), SV("Oe"), SV("OH"),
983 SV("OI"), SV("Om"), SV("OM"), SV("OS"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"), SV("Oz")},
984 std::chrono::sys_seconds(0s));
985
986 check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::sys_seconds(0s));
987 check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::sys_seconds(0s));
988 check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::sys_seconds(0s));
989 check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::sys_seconds(0s));
990 check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::sys_seconds(0s));
991
992 // Precision not allowed
993 check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::sys_seconds(0s));
994 }
995
main(int,char **)996 int main(int, char**) {
997 test<char>();
998
999 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1000 test<wchar_t>();
1001 #endif
1002
1003 return 0;
1004 }
1005