xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
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-localization
11 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12 
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 Rep, class Period, class charT>
21 //    struct formatter<chrono::duration<Rep, Period>, charT>;
22 
23 #include <chrono>
24 #include <format>
25 
26 #include <cassert>
27 #include <concepts>
28 #include <locale>
29 #include <iostream>
30 #include <ratio>
31 #include <type_traits>
32 
33 #include "formatter_tests.h"
34 #include "make_string.h"
35 #include "platform_support.h" // locale name macros
36 #include "test_macros.h"
37 
38 template <class CharT>
39 static void test_no_chrono_specs() {
40   using namespace std::literals::chrono_literals;
41 
42   check(SV("1as"), SV("{}"), std::chrono::duration<int, std::atto>(1));
43   check(SV("1fs"), SV("{}"), std::chrono::duration<int, std::femto>(1));
44   check(SV("1ps"), SV("{}"), std::chrono::duration<int, std::pico>(1));
45   check(SV("1ns"), SV("{}"), 1ns);
46 #ifndef TEST_HAS_NO_UNICODE
47   check(SV("1\u00b5s"), SV("{}"), 1us);
48 #else
49   check(SV("1us"), SV("{}"), 1us);
50 #endif
51   check(SV("1ms"), SV("{}"), 1ms);
52   check(SV("1cs"), SV("{}"), std::chrono::duration<int, std::centi>(1));
53   check(SV("1ds"), SV("{}"), std::chrono::duration<int, std::deci>(1));
54 
55   check(SV("1s"), SV("{}"), 1s);
56 
57   check(SV("1das"), SV("{}"), std::chrono::duration<int, std::deca>(1));
58   check(SV("1hs"), SV("{}"), std::chrono::duration<int, std::hecto>(1));
59   check(SV("1ks"), SV("{}"), std::chrono::duration<int, std::kilo>(1));
60   check(SV("1Ms"), SV("{}"), std::chrono::duration<int, std::mega>(1));
61   check(SV("1Gs"), SV("{}"), std::chrono::duration<int, std::giga>(1));
62   check(SV("1Ts"), SV("{}"), std::chrono::duration<int, std::tera>(1));
63   check(SV("1Ps"), SV("{}"), std::chrono::duration<int, std::peta>(1));
64   check(SV("1Es"), SV("{}"), std::chrono::duration<int, std::exa>(1));
65 
66   check(SV("1min"), SV("{}"), 1min);
67   check(SV("1h"), SV("{}"), 1h);
68   check(SV("1d"), SV("{}"), std::chrono::duration<int, std::ratio<86400>>(1));
69 
70   check(SV("1[42]s"), SV("{}"), std::chrono::duration<int, std::ratio<42>>(1));
71   check(SV("1[11]s"), SV("{}"), std::chrono::duration<int, std::ratio<33, 3>>(1));
72   check(SV("1[11/9]s"), SV("{}"), std::chrono::duration<int, std::ratio<11, 9>>(1));
73 }
74 
75 template <class CharT>
76 static void test_valid_positive_integral_values() {
77   using namespace std::literals::chrono_literals;
78 
79   constexpr std::basic_string_view<CharT> fmt = SV(
80       "{:"
81       "%%H='%H'%t"
82       "%%OH='%OH'%t"
83       "%%I='%I'%t"
84       "%%OI='%OI'%t"
85       "%%M='%M'%t"
86       "%%OM='%OM'%t"
87       "%%S='%S'%t"
88       "%%OS='%OS'%t"
89       "%%p='%p'%t"
90       "%%R='%R'%t"
91       "%%T='%T'%t"
92       "%%r='%r'%t"
93       "%%X='%X'%t"
94       "%%EX='%EX'%t"
95       "%%j='%j'%t"
96       "%%Q='%Q'%t"
97       "%%q='%q'%t"
98       "%n}");
99   constexpr std::basic_string_view<CharT> lfmt = SV(
100       "{:L"
101       "%%H='%H'%t"
102       "%%OH='%OH'%t"
103       "%%I='%I'%t"
104       "%%OI='%OI'%t"
105       "%%M='%M'%t"
106       "%%OM='%OM'%t"
107       "%%S='%S'%t"
108       "%%OS='%OS'%t"
109       "%%p='%p'%t"
110       "%%R='%R'%t"
111       "%%T='%T'%t"
112       "%%r='%r'%t"
113       "%%X='%X'%t"
114       "%%EX='%EX'%t"
115       "%%j='%j'%t"
116       "%%Q='%Q'%t"
117       "%%q='%q'%t"
118       "%n}");
119 
120   const std::locale loc(LOCALE_ja_JP_UTF_8);
121   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
122 
123   // Non localized output using C-locale
124   check(SV("%H='00'\t"
125            "%OH='00'\t"
126            "%I='12'\t"
127            "%OI='12'\t"
128            "%M='00'\t"
129            "%OM='00'\t"
130            "%S='00'\t"
131            "%OS='00'\t"
132            "%p='AM'\t"
133            "%R='00:00'\t"
134            "%T='00:00:00'\t"
135            "%r='12:00:00 AM'\t"
136            "%X='00:00:00'\t"
137            "%EX='00:00:00'\t"
138            "%j='0'\t"
139            "%Q='0'\t"
140            "%q='s'\t"
141            "\n"),
142         fmt,
143         0s);
144 
145   check(SV("%H='11'\t"
146            "%OH='11'\t"
147            "%I='11'\t"
148            "%OI='11'\t"
149            "%M='59'\t"
150            "%OM='59'\t"
151            "%S='59'\t"
152            "%OS='59'\t"
153            "%p='AM'\t"
154            "%R='11:59'\t"
155            "%T='11:59:59'\t"
156            "%r='11:59:59 AM'\t"
157            "%X='11:59:59'\t"
158            "%EX='11:59:59'\t"
159            "%j='0'\t"
160            "%Q='43199'\t"
161            "%q='s'\t"
162            "\n"),
163         fmt,
164         11h + 59min + 59s);
165 
166   check(SV("%H='12'\t"
167            "%OH='12'\t"
168            "%I='12'\t"
169            "%OI='12'\t"
170            "%M='00'\t"
171            "%OM='00'\t"
172            "%S='00'\t"
173            "%OS='00'\t"
174            "%p='PM'\t"
175            "%R='12:00'\t"
176            "%T='12:00:00'\t"
177            "%r='12:00:00 PM'\t"
178            "%X='12:00:00'\t"
179            "%EX='12:00:00'\t"
180            "%j='0'\t"
181            "%Q='12'\t"
182            "%q='h'\t"
183            "\n"),
184         fmt,
185         12h);
186 
187   check(SV("%H='23'\t"
188            "%OH='23'\t"
189            "%I='11'\t"
190            "%OI='11'\t"
191            "%M='59'\t"
192            "%OM='59'\t"
193            "%S='59'\t"
194            "%OS='59'\t"
195            "%p='PM'\t"
196            "%R='23:59'\t"
197            "%T='23:59:59'\t"
198            "%r='11:59:59 PM'\t"
199            "%X='23:59:59'\t"
200            "%EX='23:59:59'\t"
201            "%j='0'\t"
202            "%Q='86399'\t"
203            "%q='s'\t"
204            "\n"),
205         fmt,
206         23h + 59min + 59s);
207 
208   check(SV("%H='00'\t"
209            "%OH='00'\t"
210            "%I='12'\t"
211            "%OI='12'\t"
212            "%M='00'\t"
213            "%OM='00'\t"
214            "%S='00'\t"
215            "%OS='00'\t"
216            "%p='AM'\t"
217            "%R='00:00'\t"
218            "%T='00:00:00'\t"
219            "%r='12:00:00 AM'\t"
220            "%X='00:00:00'\t"
221            "%EX='00:00:00'\t"
222            "%j='7'\t"
223            "%Q='7'\t"
224            "%q='d'\t"
225            "\n"),
226         fmt,
227         std::chrono::duration<int, std::ratio<86400>>(7));
228 
229   // Use the global locale (fr_FR)
230   check(SV("%H='00'\t"
231            "%OH='00'\t"
232            "%I='12'\t"
233            "%OI='12'\t"
234            "%M='00'\t"
235            "%OM='00'\t"
236            "%S='00'\t"
237            "%OS='00'\t"
238 #if defined(_AIX)
239            "%p='AM'\t"
240 #else
241            "%p=''\t"
242 #endif
243            "%R='00:00'\t"
244            "%T='00:00:00'\t"
245 #ifdef _WIN32
246            "%r='00:00:00'\t"
247 #elif defined(_AIX)
248            "%r='12:00:00 AM'\t"
249 #elif defined(__APPLE__) || defined(__FreeBSD__)
250            "%r=''\t"
251 #else
252            "%r='12:00:00 '\t"
253 #endif
254            "%X='00:00:00'\t"
255            "%EX='00:00:00'\t"
256            "%j='0'\t"
257            "%Q='0'\t"
258            "%q='s'\t"
259            "\n"),
260         lfmt,
261         0s);
262 
263   check(SV("%H='11'\t"
264            "%OH='11'\t"
265            "%I='11'\t"
266            "%OI='11'\t"
267            "%M='59'\t"
268            "%OM='59'\t"
269            "%S='59'\t"
270            "%OS='59'\t"
271 #if defined(_AIX)
272            "%p='AM'\t"
273 #else
274            "%p=''\t"
275 #endif
276            "%R='11:59'\t"
277            "%T='11:59:59'\t"
278 #ifdef _WIN32
279            "%r='11:59:59'\t"
280 #elif defined(_AIX)
281            "%r='11:59:59 AM'\t"
282 #elif defined(__APPLE__) || defined(__FreeBSD__)
283            "%r=''\t"
284 #else
285            "%r='11:59:59 '\t"
286 #endif
287            "%X='11:59:59'\t"
288            "%EX='11:59:59'\t"
289            "%j='0'\t"
290            "%Q='43199'\t"
291            "%q='s'\t"
292            "\n"),
293         lfmt,
294         11h + 59min + 59s);
295 
296   check(SV("%H='12'\t"
297            "%OH='12'\t"
298            "%I='12'\t"
299            "%OI='12'\t"
300            "%M='00'\t"
301            "%OM='00'\t"
302            "%S='00'\t"
303            "%OS='00'\t"
304 #if defined(_AIX)
305            "%p='PM'\t"
306 #else
307            "%p=''\t"
308 #endif
309            "%R='12:00'\t"
310            "%T='12:00:00'\t"
311 #ifdef _WIN32
312            "%r='12:00:00'\t"
313 #elif defined(_AIX)
314            "%r='12:00:00 PM'\t"
315 #elif defined(__APPLE__) || defined(__FreeBSD__)
316            "%r=''\t"
317 #else
318            "%r='12:00:00 '\t"
319 #endif
320            "%X='12:00:00'\t"
321            "%EX='12:00:00'\t"
322            "%j='0'\t"
323            "%Q='12'\t"
324            "%q='h'\t"
325            "\n"),
326         lfmt,
327         12h);
328 
329   check(SV("%H='23'\t"
330            "%OH='23'\t"
331            "%I='11'\t"
332            "%OI='11'\t"
333            "%M='59'\t"
334            "%OM='59'\t"
335            "%S='59'\t"
336            "%OS='59'\t"
337 #if defined(_AIX)
338            "%p='PM'\t"
339 #else
340            "%p=''\t"
341 #endif
342            "%R='23:59'\t"
343            "%T='23:59:59'\t"
344 #if defined(_AIX)
345            "%r='11:59:59 PM'\t"
346 #elif defined(__APPLE__) || defined(__FreeBSD__)
347            "%r=''\t"
348 #elif defined(_WIN32)
349            "%r='23:59:59'\t"
350 #else
351            "%r='11:59:59 '\t"
352 #endif
353            "%X='23:59:59'\t"
354            "%EX='23:59:59'\t"
355            "%j='0'\t"
356            "%Q='86399'\t"
357            "%q='s'\t"
358            "\n"),
359         lfmt,
360         23h + 59min + 59s);
361 
362   check(SV("%H='00'\t"
363            "%OH='00'\t"
364            "%I='12'\t"
365            "%OI='12'\t"
366            "%M='00'\t"
367            "%OM='00'\t"
368            "%S='00'\t"
369            "%OS='00'\t"
370 #if defined(_AIX)
371            "%p='AM'\t"
372 #else
373            "%p=''\t"
374 #endif
375            "%R='00:00'\t"
376            "%T='00:00:00'\t"
377 #ifdef _WIN32
378            "%r='00:00:00'\t"
379 #elif defined(_AIX)
380            "%r='12:00:00 AM'\t"
381 #elif defined(__APPLE__) || defined(__FreeBSD__)
382            "%r=''\t"
383 #elif defined(_WIN32)
384            "%r='12:00:00'\t"
385 #else
386            "%r='12:00:00 '\t"
387 #endif
388            "%X='00:00:00'\t"
389            "%EX='00:00:00'\t"
390            "%j='7'\t"
391            "%Q='7'\t"
392            "%q='d'\t"
393            "\n"),
394         lfmt,
395         std::chrono::duration<int, std::ratio<86400>>(7));
396 
397   // Use supplied locale (ja_JP). This locale has a different alternate.
398 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
399   check(loc,
400         SV("%H='00'\t"
401            "%OH='00'\t"
402            "%I='12'\t"
403            "%OI='12'\t"
404            "%M='00'\t"
405            "%OM='00'\t"
406            "%S='00'\t"
407            "%OS='00'\t"
408 #  if defined(__APPLE__)
409            "%p='AM'\t"
410 #  else
411            "%p='午前'\t"
412 #  endif
413            "%R='00:00'\t"
414            "%T='00:00:00'\t"
415 #  if defined(__APPLE__) || defined(__FreeBSD__)
416 #    if defined(__APPLE__)
417            "%r='12:00:00 AM'\t"
418 #    else
419            "%r='12:00:00 午前'\t"
420 #    endif
421            "%X='00時00分00秒'\t"
422            "%EX='00時00分00秒'\t"
423 #  elif defined(_WIN32)
424            "%r='0:00:00'\t"
425            "%X='0:00:00'\t"
426            "%EX='0:00:00'\t"
427 #  else
428            "%r='午前12:00:00'\t"
429            "%X='00:00:00'\t"
430            "%EX='00:00:00'\t"
431 #  endif
432            "%j='0'\t"
433            "%Q='0'\t"
434            "%q='s'\t"
435            "\n"),
436         lfmt,
437         0s);
438 
439   check(loc,
440         SV("%H='11'\t"
441            "%OH='11'\t"
442            "%I='11'\t"
443            "%OI='11'\t"
444            "%M='59'\t"
445            "%OM='59'\t"
446            "%S='59'\t"
447            "%OS='59'\t"
448 #  if defined(__APPLE__)
449            "%p='AM'\t"
450 #  else
451            "%p='午前'\t"
452 #  endif
453            "%R='11:59'\t"
454            "%T='11:59:59'\t"
455 #  if defined(__APPLE__) || defined(__FreeBSD__)
456 #    if defined(__APPLE__)
457            "%r='11:59:59 AM'\t"
458 #    else
459            "%r='11:59:59 午前'\t"
460 #    endif
461            "%X='11時59分59秒'\t"
462            "%EX='11時59分59秒'\t"
463 #  elif defined(_WIN32)
464            "%r='11:59:59'\t"
465            "%X='11:59:59'\t"
466            "%EX='11:59:59'\t"
467 #  else
468            "%r='午前11:59:59'\t"
469            "%X='11:59:59'\t"
470            "%EX='11:59:59'\t"
471 #  endif
472            "%j='0'\t"
473            "%Q='43199'\t"
474            "%q='s'\t"
475            "\n"),
476         lfmt,
477         11h + 59min + 59s);
478 
479   check(loc,
480         SV("%H='12'\t"
481            "%OH='12'\t"
482            "%I='12'\t"
483            "%OI='12'\t"
484            "%M='00'\t"
485            "%OM='00'\t"
486            "%S='00'\t"
487            "%OS='00'\t"
488 #  if defined(__APPLE__)
489            "%p='PM'\t"
490 #  else
491            "%p='午後'\t"
492 #  endif
493            "%R='12:00'\t"
494            "%T='12:00:00'\t"
495 #  if defined(__APPLE__) || defined(__FreeBSD__)
496 #    if defined(__APPLE__)
497            "%r='12:00:00 PM'\t"
498 #    else
499            "%r='12:00:00 午後'\t"
500 #    endif
501            "%X='12時00分00秒'\t"
502            "%EX='12時00分00秒'\t"
503 #  else
504 #    ifdef _WIN32
505            "%r='12:00:00'\t"
506 #    else
507            "%r='午後12:00:00'\t"
508 #    endif
509            "%X='12:00:00'\t"
510            "%EX='12:00:00'\t"
511 #  endif
512            "%j='0'\t"
513            "%Q='12'\t"
514            "%q='h'\t"
515            "\n"),
516         lfmt,
517         12h);
518 
519   check(loc,
520         SV("%H='23'\t"
521            "%OH='23'\t"
522            "%I='11'\t"
523            "%OI='11'\t"
524            "%M='59'\t"
525            "%OM='59'\t"
526            "%S='59'\t"
527            "%OS='59'\t"
528 #  if defined(__APPLE__)
529            "%p='PM'\t"
530 #  else
531            "%p='午後'\t"
532 #  endif
533            "%R='23:59'\t"
534            "%T='23:59:59'\t"
535 #  if defined(__APPLE__) || defined(__FreeBSD__)
536 #    if defined(__APPLE__)
537            "%r='11:59:59 PM'\t"
538 #    else
539            "%r='11:59:59 午後'\t"
540 #    endif
541            "%X='23時59分59秒'\t"
542            "%EX='23時59分59秒'\t"
543 #  else
544 #    ifdef _WIN32
545            "%r='23:59:59'\t"
546 #    else
547            "%r='午後11:59:59'\t"
548 #    endif
549            "%X='23:59:59'\t"
550            "%EX='23:59:59'\t"
551 #  endif
552            "%j='0'\t"
553            "%Q='86399'\t"
554            "%q='s'\t"
555            "\n"),
556         lfmt,
557         23h + 59min + 59s);
558 
559   check(loc,
560         SV("%H='00'\t"
561            "%OH='00'\t"
562            "%I='12'\t"
563            "%OI='12'\t"
564            "%M='00'\t"
565            "%OM='00'\t"
566            "%S='00'\t"
567            "%OS='00'\t"
568 #  if defined(__APPLE__)
569            "%p='AM'\t"
570 #  else
571            "%p='午前'\t"
572 #  endif
573            "%R='00:00'\t"
574            "%T='00:00:00'\t"
575 #  if defined(__APPLE__) || defined(__FreeBSD__)
576 #    if defined(__APPLE__)
577            "%r='12:00:00 AM'\t"
578 #    else
579            "%r='12:00:00 午前'\t"
580 #    endif
581            "%X='00時00分00秒'\t"
582            "%EX='00時00分00秒'\t"
583 #  elif defined(_WIN32)
584            "%r='0:00:00'\t"
585            "%X='0:00:00'\t"
586            "%EX='0:00:00'\t"
587 #  else
588            "%r='午前12:00:00'\t"
589            "%X='00:00:00'\t"
590            "%EX='00:00:00'\t"
591 #  endif
592            "%j='7'\t"
593            "%Q='7'\t"
594            "%q='d'\t"
595            "\n"),
596         lfmt,
597         std::chrono::duration<int, std::ratio<86400>>(7));
598 #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
599   check(loc,
600         SV("%H='00'\t"
601            "%OH='〇'\t"
602            "%I='12'\t"
603            "%OI='十二'\t"
604            "%M='00'\t"
605            "%OM='〇'\t"
606            "%S='00'\t"
607            "%OS='〇'\t"
608            "%p='午前'\t"
609            "%R='00:00'\t"
610            "%T='00:00:00'\t"
611            "%r='午前12時00分00秒'\t"
612            "%X='00時00分00秒'\t"
613            "%EX='00時00分00秒'\t"
614            "%j='0'\t"
615            "%Q='0'\t"
616            "%q='s'\t"
617            "\n"),
618         lfmt,
619         0s);
620 
621   check(loc,
622         SV("%H='11'\t"
623            "%OH='十一'\t"
624            "%I='11'\t"
625            "%OI='十一'\t"
626            "%M='59'\t"
627            "%OM='五十九'\t"
628            "%S='59'\t"
629            "%OS='五十九'\t"
630            "%p='午前'\t"
631            "%R='11:59'\t"
632            "%T='11:59:59'\t"
633            "%r='午前11時59分59秒'\t"
634            "%X='11時59分59秒'\t"
635            "%EX='11時59分59秒'\t"
636            "%j='0'\t"
637            "%Q='43199'\t"
638            "%q='s'\t"
639            "\n"),
640         lfmt,
641         11h + 59min + 59s);
642 
643   check(loc,
644         SV("%H='12'\t"
645            "%OH='十二'\t"
646            "%I='12'\t"
647            "%OI='十二'\t"
648            "%M='00'\t"
649            "%OM='〇'\t"
650            "%S='00'\t"
651            "%OS='〇'\t"
652            "%p='午後'\t"
653            "%R='12:00'\t"
654            "%T='12:00:00'\t"
655            "%r='午後12時00分00秒'\t"
656            "%X='12時00分00秒'\t"
657            "%EX='12時00分00秒'\t"
658            "%j='0'\t"
659            "%Q='12'\t"
660            "%q='h'\t"
661            "\n"),
662         lfmt,
663         12h);
664 
665   check(loc,
666         SV("%H='23'\t"
667            "%OH='二十三'\t"
668            "%I='11'\t"
669            "%OI='十一'\t"
670            "%M='59'\t"
671            "%OM='五十九'\t"
672            "%S='59'\t"
673            "%OS='五十九'\t"
674            "%p='午後'\t"
675            "%R='23:59'\t"
676            "%T='23:59:59'\t"
677            "%r='午後11時59分59秒'\t"
678            "%X='23時59分59秒'\t"
679            "%EX='23時59分59秒'\t"
680            "%j='0'\t"
681            "%Q='86399'\t"
682            "%q='s'\t"
683            "\n"),
684         lfmt,
685         23h + 59min + 59s);
686 
687   check(loc,
688         SV("%H='00'\t"
689            "%OH='〇'\t"
690            "%I='12'\t"
691            "%OI='十二'\t"
692            "%M='00'\t"
693            "%OM='〇'\t"
694            "%S='00'\t"
695            "%OS='〇'\t"
696            "%p='午前'\t"
697            "%R='00:00'\t"
698            "%T='00:00:00'\t"
699            "%r='午前12時00分00秒'\t"
700            "%X='00時00分00秒'\t"
701            "%EX='00時00分00秒'\t"
702            "%j='7'\t"
703            "%Q='7'\t"
704            "%q='d'\t"
705            "\n"),
706         lfmt,
707         std::chrono::duration<int, std::ratio<86400>>(7));
708 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
709 
710   std::locale::global(std::locale::classic());
711 }
712 
713 template <class CharT>
714 static void test_valid_negative_integral_values() {
715   // [time.format]/4 The result of formatting a std::chrono::duration instance
716   // holding a negative value, or an hh_mm_ss object h for which
717   // h.is_negative() is true, is equivalent to the output of the corresponding
718   // positive value, with a STATICALLY-WIDEN<charT>("-") character sequence
719   // placed before the replacement of the initial conversion specifier.
720   //
721   // Note in this case %% is the initial conversion specifier.
722   using namespace std::literals::chrono_literals;
723 
724   constexpr std::basic_string_view<CharT> fmt = SV(
725       "{:"
726       "%%H='%H'%t"
727       "%%OH='%OH'%t"
728       "%%I='%I'%t"
729       "%%OI='%OI'%t"
730       "%%M='%M'%t"
731       "%%OM='%OM'%t"
732       "%%S='%S'%t"
733       "%%OS='%OS'%t"
734       "%%p='%p'%t"
735       "%%R='%R'%t"
736       "%%T='%T'%t"
737       "%%r='%r'%t"
738       "%%X='%X'%t"
739       "%%EX='%EX'%t"
740       "%%j='%j'%t"
741       "%%Q='%Q'%t"
742       "%%q='%q'%t"
743       "%n}");
744   constexpr std::basic_string_view<CharT> lfmt = SV(
745       "{:L"
746       "%%H='%H'%t"
747       "%%OH='%OH'%t"
748       "%%I='%I'%t"
749       "%%OI='%OI'%t"
750       "%%M='%M'%t"
751       "%%OM='%OM'%t"
752       "%%S='%S'%t"
753       "%%OS='%OS'%t"
754       "%%p='%p'%t"
755       "%%R='%R'%t"
756       "%%T='%T'%t"
757       "%%r='%r'%t"
758       "%%X='%X'%t"
759       "%%EX='%EX'%t"
760       "%%j='%j'%t"
761       "%%Q='%Q'%t"
762       "%%q='%q'%t"
763       "%n}");
764 
765   const std::locale loc(LOCALE_ja_JP_UTF_8);
766   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
767 
768   // Non localized output using C-locale
769   check(SV("-%H='23'\t"
770            "%OH='23'\t"
771            "%I='11'\t"
772            "%OI='11'\t"
773            "%M='59'\t"
774            "%OM='59'\t"
775            "%S='59'\t"
776            "%OS='59'\t"
777            "%p='PM'\t"
778            "%R='23:59'\t"
779            "%T='23:59:59'\t"
780            "%r='11:59:59 PM'\t"
781            "%X='23:59:59'\t"
782            "%EX='23:59:59'\t"
783            "%j='0'\t"
784            "%Q='86399'\t"
785            "%q='s'\t"
786            "\n"),
787         fmt,
788         -(23h + 59min + 59s));
789 
790   // Use the global locale (fr_FR)
791   check(SV("-%H='23'\t"
792            "%OH='23'\t"
793            "%I='11'\t"
794            "%OI='11'\t"
795            "%M='59'\t"
796            "%OM='59'\t"
797            "%S='59'\t"
798            "%OS='59'\t"
799 #if defined(_AIX)
800            "%p='PM'\t"
801 #else
802            "%p=''\t"
803 #endif
804            "%R='23:59'\t"
805            "%T='23:59:59'\t"
806 #if defined(_AIX)
807            "%r='11:59:59 PM'\t"
808 #elif defined(__APPLE__) || defined(__FreeBSD__)
809            "%r=''\t"
810 #elif defined(_WIN32)
811            "%r='23:59:59'\t"
812 #else
813            "%r='11:59:59 '\t"
814 #endif
815            "%X='23:59:59'\t"
816            "%EX='23:59:59'\t"
817            "%j='0'\t"
818            "%Q='86399'\t"
819            "%q='s'\t"
820            "\n"),
821         lfmt,
822         -(23h + 59min + 59s));
823 
824   // Use supplied locale (ja_JP). This locale has a different alternate.
825 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
826   check(loc,
827         SV("-%H='23'\t"
828            "%OH='23'\t"
829            "%I='11'\t"
830            "%OI='11'\t"
831            "%M='59'\t"
832            "%OM='59'\t"
833            "%S='59'\t"
834            "%OS='59'\t"
835 #  if defined(__APPLE__)
836            "%p='PM'\t"
837 #  else
838            "%p='午後'\t"
839 #  endif
840            "%R='23:59'\t"
841            "%T='23:59:59'\t"
842 #  if defined(__APPLE__) || defined(__FreeBSD__)
843 #    if defined(__APPLE__)
844            "%r='11:59:59 PM'\t"
845 #    else
846            "%r='11:59:59 午後'\t"
847 #    endif
848            "%X='23時59分59秒'\t"
849            "%EX='23時59分59秒'\t"
850 #  elif defined(_WIN32)
851            "%r='23:59:59'\t"
852            "%X='23:59:59'\t"
853            "%EX='23:59:59'\t"
854 #  else
855            "%r='午後11:59:59'\t"
856            "%X='23:59:59'\t"
857            "%EX='23:59:59'\t"
858 #  endif
859            "%j='0'\t"
860            "%Q='86399'\t"
861            "%q='s'\t"
862            "\n"),
863         lfmt,
864         -(23h + 59min + 59s));
865 #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
866   check(loc,
867         SV("-%H='23'\t"
868            "%OH='二十三'\t"
869            "%I='11'\t"
870            "%OI='十一'\t"
871            "%M='59'\t"
872            "%OM='五十九'\t"
873            "%S='59'\t"
874            "%OS='五十九'\t"
875            "%p='午後'\t"
876            "%R='23:59'\t"
877            "%T='23:59:59'\t"
878            "%r='午後11時59分59秒'\t"
879            "%X='23時59分59秒'\t"
880            "%EX='23時59分59秒'\t"
881            "%j='0'\t"
882            "%Q='86399'\t"
883            "%q='s'\t"
884            "\n"),
885         lfmt,
886         -(23h + 59min + 59s));
887 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
888   std::locale::global(std::locale::classic());
889 }
890 
891 template <class CharT>
892 static void test_valid_fractional_values() {
893   using namespace std::literals::chrono_literals;
894 
895   const std::locale loc(LOCALE_ja_JP_UTF_8);
896   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
897 
898   // Non localized output using C-locale
899   check(SV("00.000000001"), SV("{:%S}"), 1ns);
900   check(SV("00.000000501"), SV("{:%S}"), 501ns);
901   check(SV("00.000001000"), SV("{:%S}"), 1000ns);
902   check(SV("00.000000000001"), SV("{:%S}"), std::chrono::duration<int, std::pico>(1));
903   check(SV("00.000000000000001"), SV("{:%S}"), std::chrono::duration<int, std::femto>(1));
904   check(SV("00.000000000000000001"), SV("{:%S}"), std::chrono::duration<int, std::atto>(1));
905 
906   check(SV("00.001"), SV("{:%S}"), 1ms);
907   check(SV("00.01"), SV("{:%S}"), std::chrono::duration<int, std::centi>(1));
908   check(SV("00.1"), SV("{:%S}"), std::chrono::duration<int, std::deci>(1));
909   check(SV("01.1"), SV("{:%S}"), std::chrono::duration<int, std::deci>(11));
910 
911   check(SV("00.001"), SV("{:%S}"), std::chrono::duration<float, std::milli>(1.123456789));
912   check(SV("00.011"), SV("{:%S}"), std::chrono::duration<double, std::milli>(11.123456789));
913   check(SV("01"), SV("{:%S}"), std::chrono::duration<long double>(61.123456789));
914 
915   check(SV("00.000000001"), SV("{:%OS}"), 1ns);
916   check(SV("00.000000501"), SV("{:%OS}"), 501ns);
917   check(SV("00.000001000"), SV("{:%OS}"), 1000ns);
918   check(SV("00.000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::pico>(1));
919   check(SV("00.000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::femto>(1));
920   check(SV("00.000000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::atto>(1));
921 
922   check(SV("00.001"), SV("{:%OS}"), 1ms);
923   check(SV("00.01"), SV("{:%OS}"), std::chrono::duration<int, std::centi>(1));
924   check(SV("00.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(1));
925   check(SV("01.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(11));
926 
927   check(SV("00.001"), SV("{:%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
928   check(SV("00.011"), SV("{:%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
929   check(SV("01"), SV("{:%OS}"), std::chrono::duration<long double>(61.123456789));
930 
931   check(SV("01:05:06.000000001"), SV("{:%T}"), 1h + 5min + 6s + 1ns);
932   check(SV("01:05:06.000000501"), SV("{:%T}"), 1h + 5min + 6s + 501ns);
933   check(SV("01:05:06.000001000"), SV("{:%T}"), 1h + 5min + 6s + 1000ns);
934 
935   check(SV("01:05:06.001"), SV("{:%T}"), 1h + 5min + 6s + 1ms);
936   check(SV("01:05:06.01"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
937   check(SV("01:05:06.1"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
938   check(SV("01:05:07.1"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
939 
940   check(
941       SV("00:01:02"), SV("{:%T}"), std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
942   check(SV("01:05:11"),
943         SV("{:%T}"),
944         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
945             std::chrono::duration<double>(11.123456789));
946   check(SV("01:06:01"),
947         SV("{:%T}"),
948         std::chrono::duration<long double, std::ratio<3600>>(1) +
949             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
950 
951   check(SV("0"), SV("{:%j}"), std::chrono::duration<float, std::milli>(1.));
952   check(SV("1"), SV("{:%j}"), std::chrono::duration<double, std::milli>(86'400'000));
953   check(SV("1"), SV("{:%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
954 
955   check(SV("1000000"), SV("{:%Q}"), 1'000'000s);
956   check(SV("1"), SV("{:%Q}"), std::chrono::duration<float, std::milli>(1.));
957   check(SV("1.123456789"), SV("{:.6%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
958   check(SV("1.123456789"), SV("{:.9%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
959 
960   // Use the global locale (fr_FR)
961   check(SV("00,000000001"), SV("{:L%S}"), 1ns);
962   check(SV("00,000000501"), SV("{:L%S}"), 501ns);
963   check(SV("00,000001000"), SV("{:L%S}"), 1000ns);
964   check(SV("00,000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::pico>(1));
965   check(SV("00,000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::femto>(1));
966   check(SV("00,000000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::atto>(1));
967 
968   check(SV("00,001"), SV("{:L%S}"), 1ms);
969   check(SV("00,01"), SV("{:L%S}"), std::chrono::duration<int, std::centi>(1));
970   check(SV("00,1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(1));
971   check(SV("01,1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(11));
972 
973   check(SV("00,001"), SV("{:L%S}"), std::chrono::duration<float, std::milli>(1.123456789));
974   check(SV("00,011"), SV("{:L%S}"), std::chrono::duration<double, std::milli>(11.123456789));
975   check(SV("01"), SV("{:L%S}"), std::chrono::duration<long double>(61.123456789));
976 
977   check(SV("00,000000001"), SV("{:L%OS}"), 1ns);
978   check(SV("00,000000501"), SV("{:L%OS}"), 501ns);
979   check(SV("00,000001000"), SV("{:L%OS}"), 1000ns);
980   check(SV("00,000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::pico>(1));
981   check(SV("00,000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::femto>(1));
982   check(SV("00,000000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::atto>(1));
983 
984   check(SV("00,001"), SV("{:L%OS}"), 1ms);
985   check(SV("00,01"), SV("{:L%OS}"), std::chrono::duration<int, std::centi>(1));
986   check(SV("00,1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(1));
987   check(SV("01,1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(11));
988 
989   check(SV("00,001"), SV("{:L%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
990   check(SV("00,011"), SV("{:L%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
991   check(SV("01"), SV("{:L%OS}"), std::chrono::duration<long double>(61.123456789));
992 
993   check(SV("01:05:06,000000001"), SV("{:L%T}"), 1h + 5min + 6s + 1ns);
994   check(SV("01:05:06,000000501"), SV("{:L%T}"), 1h + 5min + 6s + 501ns);
995   check(SV("01:05:06,000001000"), SV("{:L%T}"), 1h + 5min + 6s + 1000ns);
996 
997   check(SV("01:05:06,001"), SV("{:L%T}"), 1h + 5min + 6s + 1ms);
998   check(SV("01:05:06,01"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
999   check(SV("01:05:06,1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
1000   check(SV("01:05:07,1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
1001 
1002   check(SV("00:01:02"),
1003         SV("{:L%T}"),
1004         std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
1005   check(SV("01:05:11"),
1006         SV("{:L%T}"),
1007         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
1008             std::chrono::duration<double>(11.123456789));
1009   check(SV("01:06:01"),
1010         SV("{:L%T}"),
1011         std::chrono::duration<long double, std::ratio<3600>>(1) +
1012             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
1013 
1014   check(SV("0"), SV("{:L%j}"), std::chrono::duration<float, std::milli>(1.));
1015   check(SV("1"), SV("{:L%j}"), std::chrono::duration<double, std::milli>(86'400'000));
1016   check(SV("1"), SV("{:L%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
1017 
1018   check(SV("1000000"), SV("{:L%Q}"), 1'000'000s); // The Standard mandates not localized.
1019   check(SV("1"), SV("{:L%Q}"), std::chrono::duration<float, std::milli>(1.));
1020   check(SV("1.123456789"), SV("{:.6L%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
1021   check(SV("1.123456789"), SV("{:.9L%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
1022 
1023   // Use supplied locale (ja_JP). This locale has a different alternate.
1024   check(loc, SV("00.000000001"), SV("{:L%S}"), 1ns);
1025   check(loc, SV("00.000000501"), SV("{:L%S}"), 501ns);
1026   check(loc, SV("00.000001000"), SV("{:L%S}"), 1000ns);
1027   check(loc, SV("00.000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::pico>(1));
1028   check(loc, SV("00.000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::femto>(1));
1029   check(loc, SV("00.000000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::atto>(1));
1030 
1031   check(loc, SV("00.001"), SV("{:L%S}"), 1ms);
1032   check(loc, SV("00.01"), SV("{:L%S}"), std::chrono::duration<int, std::centi>(1));
1033   check(loc, SV("00.1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(1));
1034   check(loc, SV("01.1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(11));
1035 
1036   check(loc, SV("00.001"), SV("{:L%S}"), std::chrono::duration<float, std::milli>(1.123456789));
1037   check(loc, SV("00.011"), SV("{:L%S}"), std::chrono::duration<double, std::milli>(11.123456789));
1038   check(loc, SV("01"), SV("{:L%S}"), std::chrono::duration<long double>(61.123456789));
1039 
1040 #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
1041 
1042   check(SV("00.000000001"), SV("{:%OS}"), 1ns);
1043   check(SV("00.000000501"), SV("{:%OS}"), 501ns);
1044   check(SV("00.000001000"), SV("{:%OS}"), 1000ns);
1045   check(SV("00.000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::pico>(1));
1046   check(SV("00.000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::femto>(1));
1047   check(SV("00.000000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::atto>(1));
1048 
1049   check(SV("00.001"), SV("{:%OS}"), 1ms);
1050   check(SV("00.01"), SV("{:%OS}"), std::chrono::duration<int, std::centi>(1));
1051   check(SV("00.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(1));
1052   check(SV("01.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(11));
1053 
1054   check(SV("00.001"), SV("{:%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
1055   check(SV("00.011"), SV("{:%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
1056   check(SV("01"), SV("{:%OS}"), std::chrono::duration<long double>(61.123456789));
1057 #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
1058 
1059   check(loc, SV("〇.000000001"), SV("{:L%OS}"), 1ns);
1060   check(loc, SV("〇.000000501"), SV("{:L%OS}"), 501ns);
1061   check(loc, SV("〇.000001000"), SV("{:L%OS}"), 1000ns);
1062   check(loc, SV("〇.000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::pico>(1));
1063   check(loc, SV("〇.000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::femto>(1));
1064   check(loc, SV("〇.000000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::atto>(1));
1065 
1066   check(loc, SV("〇.001"), SV("{:L%OS}"), 1ms);
1067   check(loc, SV("〇.01"), SV("{:L%OS}"), std::chrono::duration<int, std::centi>(1));
1068   check(loc, SV("〇.1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(1));
1069   check(loc, SV("一.1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(11));
1070 
1071   check(loc, SV("〇.001"), SV("{:L%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
1072   check(loc, SV("〇.011"), SV("{:L%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
1073   check(loc, SV("一"), SV("{:L%OS}"), std::chrono::duration<long double>(61.123456789));
1074 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
1075 
1076   check(loc, SV("01:05:06.000000001"), SV("{:L%T}"), 1h + 5min + 6s + 1ns);
1077   check(loc, SV("01:05:06.000000501"), SV("{:L%T}"), 1h + 5min + 6s + 501ns);
1078   check(loc, SV("01:05:06.000001000"), SV("{:L%T}"), 1h + 5min + 6s + 1000ns);
1079 
1080   check(loc, SV("01:05:06.001"), SV("{:L%T}"), 1h + 5min + 6s + 1ms);
1081   check(loc, SV("01:05:06.01"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
1082   check(loc, SV("01:05:06.1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
1083   check(loc, SV("01:05:07.1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
1084 
1085   check(loc,
1086         SV("00:01:02"),
1087         SV("{:L%T}"),
1088         std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
1089   check(loc,
1090         SV("01:05:11"),
1091         SV("{:L%T}"),
1092         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
1093             std::chrono::duration<double>(11.123456789));
1094   check(loc,
1095         SV("01:06:01"),
1096         SV("{:L%T}"),
1097         std::chrono::duration<long double, std::ratio<3600>>(1) +
1098             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
1099 
1100   check(loc, SV("0"), SV("{:L%j}"), std::chrono::duration<float, std::milli>(1.));
1101   check(loc, SV("1"), SV("{:L%j}"), std::chrono::duration<double, std::milli>(86'400'000));
1102   check(loc, SV("1"), SV("{:L%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
1103 
1104   check(loc, SV("1000000"), SV("{:L%Q}"), 1'000'000s); // The Standard mandates not localized.
1105   check(loc, SV("1"), SV("{:L%Q}"), std::chrono::duration<float, std::milli>(1.));
1106   check(loc, SV("1.123456789"), SV("{:.6L%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
1107   check(loc, SV("1.123456789"), SV("{:.9L%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
1108 
1109   std::locale::global(std::locale::classic());
1110 }
1111 
1112 template <class CharT>
1113 static void test_valid_values() {
1114   test_valid_positive_integral_values<CharT>();
1115   test_valid_negative_integral_values<CharT>();
1116   test_valid_fractional_values<CharT>();
1117 }
1118 
1119 template <class CharT>
1120 static void test_pr62082() {
1121   // Examples in https://llvm.org/PR62082
1122   check(SV("39.223300"), SV("{:%S}"), std::chrono::duration<int, std::ratio<101, 103>>{40});
1123   check(SV("01.4755859375"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1511});
1124 
1125   // Test with all possible number of decimals [0, 18]. When it does not
1126   // fit in 18 decimals it uses 6.
1127   check(SV("05"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 1>>{5}); // 0
1128 
1129   check(SV("05.0"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 2>>{10}); // 1
1130   check(SV("05.5"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2>>{11});   // 1
1131 
1132   check(SV("01.00"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4>>{4});         // 2
1133   check(SV("01.50"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 4>>{6});      // 2
1134   check(SV("01.75"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 4>>{7}); // 2
1135 
1136   check(SV("01.000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8>>{8});                          // 3
1137   check(SV("01.0000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16>>{16});                       // 4
1138   check(SV("01.00000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32>>{32});                      // 5
1139   check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 64>>{64});                     // 6
1140   check(SV("01.0000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 128>>{128});                  // 7
1141   check(SV("01.00000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 256>>{256});                 // 8
1142   check(SV("01.000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 512>>{512});                // 9
1143   check(SV("01.0000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1024});             // 10
1144   check(SV("01.00000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2048>>{2048});            // 11
1145   check(SV("01.000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4096>>{4096});           // 12
1146   check(SV("01.0000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8192>>{8192});          // 13
1147   check(SV("01.00000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16384>>{16384});       // 14
1148   check(SV("01.000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32768>>{32768});      // 15
1149   check(SV("01.0000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 65536>>{65536});     // 16
1150   check(SV("01.00000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 131072>>{131072});  // 17
1151   check(SV("01.000000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 262144>>{262144}); // 18
1152   check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 524288>>{524288});             // 19 -> 6
1153 
1154   // Infinite number of decimals will use 6 decimals.
1155   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 9>>{1});
1156   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 9>>{1});
1157   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 9>>{1});
1158   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 9>>{1});
1159 }
1160 
1161 template <class CharT>
1162 static void test_unsigned_duration() {
1163   // Reported in https://github.com/llvm/llvm-project/issues/96820
1164   using namespace std::literals::chrono_literals;
1165 
1166   check(SV("1as"), SV("{}"), std::chrono::duration<unsigned short, std::atto>(1));
1167   check(SV("1fs"), SV("{}"), std::chrono::duration<unsigned, std::femto>(1));
1168   check(SV("1ps"), SV("{}"), std::chrono::duration<unsigned long, std::pico>(1));
1169   check(SV("1ns"), SV("{}"), std::chrono::duration<unsigned long long, std::nano>(1));
1170 }
1171 
1172 template <class CharT>
1173 static void test() {
1174   using namespace std::literals::chrono_literals;
1175 
1176   test_no_chrono_specs<CharT>();
1177   test_valid_values<CharT>();
1178   test_unsigned_duration<CharT>();
1179   test_pr62082<CharT>();
1180 
1181   check_invalid_types<CharT>(
1182       {SV("H"), SV("I"), SV("j"), SV("M"), SV("n"), SV("O"),  SV("p"),  SV("q"),  SV("Q"),  SV("r"),
1183        SV("R"), SV("S"), SV("t"), SV("T"), SV("X"), SV("EX"), SV("OH"), SV("OI"), SV("OM"), SV("OS")},
1184       0ms);
1185 
1186   check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), 0ms);
1187   check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), 0ms);
1188   check_exception("End of input while parsing a conversion specifier", SV("{:%"), 0ms);
1189   check_exception("End of input while parsing the modifier E", SV("{:%E"), 0ms);
1190   check_exception("End of input while parsing the modifier O", SV("{:%O"), 0ms);
1191 
1192   // Make sure the required values work, based on their minimum number of required bits per [time.syn].
1193   check(SV("23:47:16.854775807"),
1194         SV("{:%T}"),
1195         std::chrono::nanoseconds{0x7fff'ffff'ffff'ffffll}); // 64 bit signed value max
1196   check(SV("23:35:09.481983"),
1197         SV("{:%T}"),
1198         std::chrono::microseconds{0x003f'ffff'ffff'ffffll});                                 // 55 bit signed value max
1199   check(SV("06:20:44.415"), SV("{:%T}"), std::chrono::milliseconds{0x0000'fff'ffff'ffffll}); // 45 bit signed value max
1200   check(SV("01:53:03"), SV("{:%T}"), std::chrono::seconds{0x0000'0003'ffff'ffffll});         // 35 bit signed value max
1201   check(SV("12:15:00"), SV("{:%T}"), std::chrono::minutes{0x0fff'ffff});                     // 29 bit signed value max
1202   check(SV("15:00:00"), SV("{:%T}"), std::chrono::hours{0x003f'ffff});                       // 23 bit signed value max
1203   check(SV("00:00:00"), SV("{:%T}"), std::chrono::days{0x0ff'ffff});                         // 25 bit signed value max
1204   check(SV("00:00:00"), SV("{:%T}"), std::chrono::weeks{0x003f'ffff});                       // 22 bit signed value max
1205   check(SV("21:11:42"), SV("{:%T}"), std::chrono::months{0x0007'ffff});                      // 20 bit signed value max
1206   check(SV("05:42:00"), SV("{:%T}"), std::chrono::years{0xffff});                            // 17 bit signed value max
1207 
1208   // Precision not allowed
1209   check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), 0ms);
1210 }
1211 
1212 int main(int, char**) {
1213   test<char>();
1214 
1215 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1216   test<wchar_t>();
1217 #endif
1218 
1219   return 0;
1220 }
1221