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

source code of libcxx/test/std/time/time.syn/formatter.tai_time.pass.cpp