xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.duration.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1719c3dc6SMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3719c3dc6SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4719c3dc6SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5719c3dc6SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6719c3dc6SMark de Wever //
7719c3dc6SMark de Wever //===----------------------------------------------------------------------===//
8719c3dc6SMark de Wever 
9719c3dc6SMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17
10719c3dc6SMark de Wever // UNSUPPORTED: no-localization
11520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12719c3dc6SMark de Wever 
13f0fc8c48SLouis Dionne // XFAIL: availability-fp_to_chars-missing
143d334df5SLouis Dionne 
15719c3dc6SMark de Wever // REQUIRES: locale.fr_FR.UTF-8
16719c3dc6SMark de Wever // REQUIRES: locale.ja_JP.UTF-8
17719c3dc6SMark de Wever 
18719c3dc6SMark de Wever // <chrono>
19719c3dc6SMark de Wever 
20719c3dc6SMark de Wever //  template<class Rep, class Period, class charT>
21719c3dc6SMark de Wever //    struct formatter<chrono::duration<Rep, Period>, charT>;
22719c3dc6SMark de Wever 
23719c3dc6SMark de Wever #include <chrono>
24719c3dc6SMark de Wever #include <format>
25719c3dc6SMark de Wever 
26719c3dc6SMark de Wever #include <cassert>
27719c3dc6SMark de Wever #include <concepts>
28719c3dc6SMark de Wever #include <locale>
29719c3dc6SMark de Wever #include <iostream>
30e655d8a5SNikolas Klauser #include <ratio>
31719c3dc6SMark de Wever #include <type_traits>
32719c3dc6SMark de Wever 
33719c3dc6SMark de Wever #include "formatter_tests.h"
34719c3dc6SMark de Wever #include "make_string.h"
35719c3dc6SMark de Wever #include "platform_support.h" // locale name macros
36719c3dc6SMark de Wever #include "test_macros.h"
37719c3dc6SMark de Wever 
38719c3dc6SMark de Wever template <class CharT>
39719c3dc6SMark de Wever static void test_no_chrono_specs() {
40719c3dc6SMark de Wever   using namespace std::literals::chrono_literals;
41719c3dc6SMark de Wever 
42719c3dc6SMark de Wever   check(SV("1as"), SV("{}"), std::chrono::duration<int, std::atto>(1));
43719c3dc6SMark de Wever   check(SV("1fs"), SV("{}"), std::chrono::duration<int, std::femto>(1));
44719c3dc6SMark de Wever   check(SV("1ps"), SV("{}"), std::chrono::duration<int, std::pico>(1));
45719c3dc6SMark de Wever   check(SV("1ns"), SV("{}"), 1ns);
46719c3dc6SMark de Wever #ifndef TEST_HAS_NO_UNICODE
47719c3dc6SMark de Wever   check(SV("1\u00b5s"), SV("{}"), 1us);
48719c3dc6SMark de Wever #else
49719c3dc6SMark de Wever   check(SV("1us"), SV("{}"), 1us);
50719c3dc6SMark de Wever #endif
51719c3dc6SMark de Wever   check(SV("1ms"), SV("{}"), 1ms);
52719c3dc6SMark de Wever   check(SV("1cs"), SV("{}"), std::chrono::duration<int, std::centi>(1));
53719c3dc6SMark de Wever   check(SV("1ds"), SV("{}"), std::chrono::duration<int, std::deci>(1));
54719c3dc6SMark de Wever 
55719c3dc6SMark de Wever   check(SV("1s"), SV("{}"), 1s);
56719c3dc6SMark de Wever 
57719c3dc6SMark de Wever   check(SV("1das"), SV("{}"), std::chrono::duration<int, std::deca>(1));
58719c3dc6SMark de Wever   check(SV("1hs"), SV("{}"), std::chrono::duration<int, std::hecto>(1));
59719c3dc6SMark de Wever   check(SV("1ks"), SV("{}"), std::chrono::duration<int, std::kilo>(1));
60719c3dc6SMark de Wever   check(SV("1Ms"), SV("{}"), std::chrono::duration<int, std::mega>(1));
61719c3dc6SMark de Wever   check(SV("1Gs"), SV("{}"), std::chrono::duration<int, std::giga>(1));
62719c3dc6SMark de Wever   check(SV("1Ts"), SV("{}"), std::chrono::duration<int, std::tera>(1));
63719c3dc6SMark de Wever   check(SV("1Ps"), SV("{}"), std::chrono::duration<int, std::peta>(1));
64719c3dc6SMark de Wever   check(SV("1Es"), SV("{}"), std::chrono::duration<int, std::exa>(1));
65719c3dc6SMark de Wever 
66719c3dc6SMark de Wever   check(SV("1min"), SV("{}"), 1min);
67719c3dc6SMark de Wever   check(SV("1h"), SV("{}"), 1h);
68719c3dc6SMark de Wever   check(SV("1d"), SV("{}"), std::chrono::duration<int, std::ratio<86400>>(1));
69719c3dc6SMark de Wever 
70719c3dc6SMark de Wever   check(SV("1[42]s"), SV("{}"), std::chrono::duration<int, std::ratio<42>>(1));
71719c3dc6SMark de Wever   check(SV("1[11]s"), SV("{}"), std::chrono::duration<int, std::ratio<33, 3>>(1));
72719c3dc6SMark de Wever   check(SV("1[11/9]s"), SV("{}"), std::chrono::duration<int, std::ratio<11, 9>>(1));
73719c3dc6SMark de Wever }
74719c3dc6SMark de Wever 
75719c3dc6SMark de Wever template <class CharT>
76719c3dc6SMark de Wever static void test_valid_positive_integral_values() {
77719c3dc6SMark de Wever   using namespace std::literals::chrono_literals;
78719c3dc6SMark de Wever 
79719c3dc6SMark de Wever   constexpr std::basic_string_view<CharT> fmt = SV(
80719c3dc6SMark de Wever       "{:"
81719c3dc6SMark de Wever       "%%H='%H'%t"
82719c3dc6SMark de Wever       "%%OH='%OH'%t"
83719c3dc6SMark de Wever       "%%I='%I'%t"
84719c3dc6SMark de Wever       "%%OI='%OI'%t"
85719c3dc6SMark de Wever       "%%M='%M'%t"
86719c3dc6SMark de Wever       "%%OM='%OM'%t"
87719c3dc6SMark de Wever       "%%S='%S'%t"
88719c3dc6SMark de Wever       "%%OS='%OS'%t"
89719c3dc6SMark de Wever       "%%p='%p'%t"
90719c3dc6SMark de Wever       "%%R='%R'%t"
91719c3dc6SMark de Wever       "%%T='%T'%t"
92719c3dc6SMark de Wever       "%%r='%r'%t"
93719c3dc6SMark de Wever       "%%X='%X'%t"
94719c3dc6SMark de Wever       "%%EX='%EX'%t"
95719c3dc6SMark de Wever       "%%j='%j'%t"
96719c3dc6SMark de Wever       "%%Q='%Q'%t"
97719c3dc6SMark de Wever       "%%q='%q'%t"
98719c3dc6SMark de Wever       "%n}");
99719c3dc6SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV(
100719c3dc6SMark de Wever       "{:L"
101719c3dc6SMark de Wever       "%%H='%H'%t"
102719c3dc6SMark de Wever       "%%OH='%OH'%t"
103719c3dc6SMark de Wever       "%%I='%I'%t"
104719c3dc6SMark de Wever       "%%OI='%OI'%t"
105719c3dc6SMark de Wever       "%%M='%M'%t"
106719c3dc6SMark de Wever       "%%OM='%OM'%t"
107719c3dc6SMark de Wever       "%%S='%S'%t"
108719c3dc6SMark de Wever       "%%OS='%OS'%t"
109719c3dc6SMark de Wever       "%%p='%p'%t"
110719c3dc6SMark de Wever       "%%R='%R'%t"
111719c3dc6SMark de Wever       "%%T='%T'%t"
112719c3dc6SMark de Wever       "%%r='%r'%t"
113719c3dc6SMark de Wever       "%%X='%X'%t"
114719c3dc6SMark de Wever       "%%EX='%EX'%t"
115719c3dc6SMark de Wever       "%%j='%j'%t"
116719c3dc6SMark de Wever       "%%Q='%Q'%t"
117719c3dc6SMark de Wever       "%%q='%q'%t"
118719c3dc6SMark de Wever       "%n}");
119719c3dc6SMark de Wever 
120719c3dc6SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
121719c3dc6SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
122719c3dc6SMark de Wever 
123719c3dc6SMark de Wever   // Non localized output using C-locale
124719c3dc6SMark de Wever   check(SV("%H='00'\t"
125719c3dc6SMark de Wever            "%OH='00'\t"
126719c3dc6SMark de Wever            "%I='12'\t"
127719c3dc6SMark de Wever            "%OI='12'\t"
128719c3dc6SMark de Wever            "%M='00'\t"
129719c3dc6SMark de Wever            "%OM='00'\t"
130719c3dc6SMark de Wever            "%S='00'\t"
131719c3dc6SMark de Wever            "%OS='00'\t"
132719c3dc6SMark de Wever            "%p='AM'\t"
133719c3dc6SMark de Wever            "%R='00:00'\t"
134719c3dc6SMark de Wever            "%T='00:00:00'\t"
135719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
136719c3dc6SMark de Wever            "%X='00:00:00'\t"
137719c3dc6SMark de Wever            "%EX='00:00:00'\t"
138719c3dc6SMark de Wever            "%j='0'\t"
139719c3dc6SMark de Wever            "%Q='0'\t"
140719c3dc6SMark de Wever            "%q='s'\t"
141719c3dc6SMark de Wever            "\n"),
142719c3dc6SMark de Wever         fmt,
143719c3dc6SMark de Wever         0s);
144719c3dc6SMark de Wever 
145719c3dc6SMark de Wever   check(SV("%H='11'\t"
146719c3dc6SMark de Wever            "%OH='11'\t"
147719c3dc6SMark de Wever            "%I='11'\t"
148719c3dc6SMark de Wever            "%OI='11'\t"
149719c3dc6SMark de Wever            "%M='59'\t"
150719c3dc6SMark de Wever            "%OM='59'\t"
151719c3dc6SMark de Wever            "%S='59'\t"
152719c3dc6SMark de Wever            "%OS='59'\t"
153719c3dc6SMark de Wever            "%p='AM'\t"
154719c3dc6SMark de Wever            "%R='11:59'\t"
155719c3dc6SMark de Wever            "%T='11:59:59'\t"
156719c3dc6SMark de Wever            "%r='11:59:59 AM'\t"
157719c3dc6SMark de Wever            "%X='11:59:59'\t"
158719c3dc6SMark de Wever            "%EX='11:59:59'\t"
159719c3dc6SMark de Wever            "%j='0'\t"
160719c3dc6SMark de Wever            "%Q='43199'\t"
161719c3dc6SMark de Wever            "%q='s'\t"
162719c3dc6SMark de Wever            "\n"),
163719c3dc6SMark de Wever         fmt,
164719c3dc6SMark de Wever         11h + 59min + 59s);
165719c3dc6SMark de Wever 
166719c3dc6SMark de Wever   check(SV("%H='12'\t"
167719c3dc6SMark de Wever            "%OH='12'\t"
168719c3dc6SMark de Wever            "%I='12'\t"
169719c3dc6SMark de Wever            "%OI='12'\t"
170719c3dc6SMark de Wever            "%M='00'\t"
171719c3dc6SMark de Wever            "%OM='00'\t"
172719c3dc6SMark de Wever            "%S='00'\t"
173719c3dc6SMark de Wever            "%OS='00'\t"
174719c3dc6SMark de Wever            "%p='PM'\t"
175719c3dc6SMark de Wever            "%R='12:00'\t"
176719c3dc6SMark de Wever            "%T='12:00:00'\t"
177719c3dc6SMark de Wever            "%r='12:00:00 PM'\t"
178719c3dc6SMark de Wever            "%X='12:00:00'\t"
179719c3dc6SMark de Wever            "%EX='12:00:00'\t"
180719c3dc6SMark de Wever            "%j='0'\t"
181719c3dc6SMark de Wever            "%Q='12'\t"
182719c3dc6SMark de Wever            "%q='h'\t"
183719c3dc6SMark de Wever            "\n"),
184719c3dc6SMark de Wever         fmt,
185719c3dc6SMark de Wever         12h);
186719c3dc6SMark de Wever 
187719c3dc6SMark de Wever   check(SV("%H='23'\t"
188719c3dc6SMark de Wever            "%OH='23'\t"
189719c3dc6SMark de Wever            "%I='11'\t"
190719c3dc6SMark de Wever            "%OI='11'\t"
191719c3dc6SMark de Wever            "%M='59'\t"
192719c3dc6SMark de Wever            "%OM='59'\t"
193719c3dc6SMark de Wever            "%S='59'\t"
194719c3dc6SMark de Wever            "%OS='59'\t"
195719c3dc6SMark de Wever            "%p='PM'\t"
196719c3dc6SMark de Wever            "%R='23:59'\t"
197719c3dc6SMark de Wever            "%T='23:59:59'\t"
198719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
199719c3dc6SMark de Wever            "%X='23:59:59'\t"
200719c3dc6SMark de Wever            "%EX='23:59:59'\t"
201719c3dc6SMark de Wever            "%j='0'\t"
202719c3dc6SMark de Wever            "%Q='86399'\t"
203719c3dc6SMark de Wever            "%q='s'\t"
204719c3dc6SMark de Wever            "\n"),
205719c3dc6SMark de Wever         fmt,
206719c3dc6SMark de Wever         23h + 59min + 59s);
207719c3dc6SMark de Wever 
208719c3dc6SMark de Wever   check(SV("%H='00'\t"
209719c3dc6SMark de Wever            "%OH='00'\t"
210719c3dc6SMark de Wever            "%I='12'\t"
211719c3dc6SMark de Wever            "%OI='12'\t"
212719c3dc6SMark de Wever            "%M='00'\t"
213719c3dc6SMark de Wever            "%OM='00'\t"
214719c3dc6SMark de Wever            "%S='00'\t"
215719c3dc6SMark de Wever            "%OS='00'\t"
216719c3dc6SMark de Wever            "%p='AM'\t"
217719c3dc6SMark de Wever            "%R='00:00'\t"
218719c3dc6SMark de Wever            "%T='00:00:00'\t"
219719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
220719c3dc6SMark de Wever            "%X='00:00:00'\t"
221719c3dc6SMark de Wever            "%EX='00:00:00'\t"
222719c3dc6SMark de Wever            "%j='7'\t"
223719c3dc6SMark de Wever            "%Q='7'\t"
224719c3dc6SMark de Wever            "%q='d'\t"
225719c3dc6SMark de Wever            "\n"),
226719c3dc6SMark de Wever         fmt,
227719c3dc6SMark de Wever         std::chrono::duration<int, std::ratio<86400>>(7));
228719c3dc6SMark de Wever 
229719c3dc6SMark de Wever   // Use the global locale (fr_FR)
230719c3dc6SMark de Wever   check(SV("%H='00'\t"
231719c3dc6SMark de Wever            "%OH='00'\t"
232719c3dc6SMark de Wever            "%I='12'\t"
233719c3dc6SMark de Wever            "%OI='12'\t"
234719c3dc6SMark de Wever            "%M='00'\t"
235719c3dc6SMark de Wever            "%OM='00'\t"
236719c3dc6SMark de Wever            "%S='00'\t"
237719c3dc6SMark de Wever            "%OS='00'\t"
238719c3dc6SMark de Wever #if defined(_AIX)
239719c3dc6SMark de Wever            "%p='AM'\t"
240719c3dc6SMark de Wever #else
241719c3dc6SMark de Wever            "%p=''\t"
242719c3dc6SMark de Wever #endif
243719c3dc6SMark de Wever            "%R='00:00'\t"
244719c3dc6SMark de Wever            "%T='00:00:00'\t"
245719c3dc6SMark de Wever #ifdef _WIN32
2461403080aSMark de Wever            "%r='00:00:00'\t"
247719c3dc6SMark de Wever #elif defined(_AIX)
248719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
2498f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
250719c3dc6SMark de Wever            "%r=''\t"
251719c3dc6SMark de Wever #else
252719c3dc6SMark de Wever            "%r='12:00:00 '\t"
253719c3dc6SMark de Wever #endif
254719c3dc6SMark de Wever            "%X='00:00:00'\t"
255719c3dc6SMark de Wever            "%EX='00:00:00'\t"
256719c3dc6SMark de Wever            "%j='0'\t"
257719c3dc6SMark de Wever            "%Q='0'\t"
258719c3dc6SMark de Wever            "%q='s'\t"
259719c3dc6SMark de Wever            "\n"),
260719c3dc6SMark de Wever         lfmt,
261719c3dc6SMark de Wever         0s);
262719c3dc6SMark de Wever 
263719c3dc6SMark de Wever   check(SV("%H='11'\t"
264719c3dc6SMark de Wever            "%OH='11'\t"
265719c3dc6SMark de Wever            "%I='11'\t"
266719c3dc6SMark de Wever            "%OI='11'\t"
267719c3dc6SMark de Wever            "%M='59'\t"
268719c3dc6SMark de Wever            "%OM='59'\t"
269719c3dc6SMark de Wever            "%S='59'\t"
270719c3dc6SMark de Wever            "%OS='59'\t"
271719c3dc6SMark de Wever #if defined(_AIX)
272719c3dc6SMark de Wever            "%p='AM'\t"
273719c3dc6SMark de Wever #else
274719c3dc6SMark de Wever            "%p=''\t"
275719c3dc6SMark de Wever #endif
276719c3dc6SMark de Wever            "%R='11:59'\t"
277719c3dc6SMark de Wever            "%T='11:59:59'\t"
278719c3dc6SMark de Wever #ifdef _WIN32
279719c3dc6SMark de Wever            "%r='11:59:59'\t"
280719c3dc6SMark de Wever #elif defined(_AIX)
281719c3dc6SMark de Wever            "%r='11:59:59 AM'\t"
2828f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
283719c3dc6SMark de Wever            "%r=''\t"
284719c3dc6SMark de Wever #else
285719c3dc6SMark de Wever            "%r='11:59:59 '\t"
286719c3dc6SMark de Wever #endif
287719c3dc6SMark de Wever            "%X='11:59:59'\t"
288719c3dc6SMark de Wever            "%EX='11:59:59'\t"
289719c3dc6SMark de Wever            "%j='0'\t"
290719c3dc6SMark de Wever            "%Q='43199'\t"
291719c3dc6SMark de Wever            "%q='s'\t"
292719c3dc6SMark de Wever            "\n"),
293719c3dc6SMark de Wever         lfmt,
294719c3dc6SMark de Wever         11h + 59min + 59s);
295719c3dc6SMark de Wever 
296719c3dc6SMark de Wever   check(SV("%H='12'\t"
297719c3dc6SMark de Wever            "%OH='12'\t"
298719c3dc6SMark de Wever            "%I='12'\t"
299719c3dc6SMark de Wever            "%OI='12'\t"
300719c3dc6SMark de Wever            "%M='00'\t"
301719c3dc6SMark de Wever            "%OM='00'\t"
302719c3dc6SMark de Wever            "%S='00'\t"
303719c3dc6SMark de Wever            "%OS='00'\t"
304719c3dc6SMark de Wever #if defined(_AIX)
305719c3dc6SMark de Wever            "%p='PM'\t"
306719c3dc6SMark de Wever #else
307719c3dc6SMark de Wever            "%p=''\t"
308719c3dc6SMark de Wever #endif
309719c3dc6SMark de Wever            "%R='12:00'\t"
310719c3dc6SMark de Wever            "%T='12:00:00'\t"
311719c3dc6SMark de Wever #ifdef _WIN32
3121403080aSMark de Wever            "%r='12:00:00'\t"
313719c3dc6SMark de Wever #elif defined(_AIX)
314719c3dc6SMark de Wever            "%r='12:00:00 PM'\t"
3158f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
316719c3dc6SMark de Wever            "%r=''\t"
317719c3dc6SMark de Wever #else
318719c3dc6SMark de Wever            "%r='12:00:00 '\t"
319719c3dc6SMark de Wever #endif
320719c3dc6SMark de Wever            "%X='12:00:00'\t"
321719c3dc6SMark de Wever            "%EX='12:00:00'\t"
322719c3dc6SMark de Wever            "%j='0'\t"
323719c3dc6SMark de Wever            "%Q='12'\t"
324719c3dc6SMark de Wever            "%q='h'\t"
325719c3dc6SMark de Wever            "\n"),
326719c3dc6SMark de Wever         lfmt,
327719c3dc6SMark de Wever         12h);
328719c3dc6SMark de Wever 
329719c3dc6SMark de Wever   check(SV("%H='23'\t"
330719c3dc6SMark de Wever            "%OH='23'\t"
331719c3dc6SMark de Wever            "%I='11'\t"
332719c3dc6SMark de Wever            "%OI='11'\t"
333719c3dc6SMark de Wever            "%M='59'\t"
334719c3dc6SMark de Wever            "%OM='59'\t"
335719c3dc6SMark de Wever            "%S='59'\t"
336719c3dc6SMark de Wever            "%OS='59'\t"
337719c3dc6SMark de Wever #if defined(_AIX)
338719c3dc6SMark de Wever            "%p='PM'\t"
339719c3dc6SMark de Wever #else
340719c3dc6SMark de Wever            "%p=''\t"
341719c3dc6SMark de Wever #endif
342719c3dc6SMark de Wever            "%R='23:59'\t"
343719c3dc6SMark de Wever            "%T='23:59:59'\t"
344719c3dc6SMark de Wever #if defined(_AIX)
345719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
3468f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
347719c3dc6SMark de Wever            "%r=''\t"
3481403080aSMark de Wever #elif defined(_WIN32)
3491403080aSMark de Wever            "%r='23:59:59'\t"
350719c3dc6SMark de Wever #else
351719c3dc6SMark de Wever            "%r='11:59:59 '\t"
352719c3dc6SMark de Wever #endif
353719c3dc6SMark de Wever            "%X='23:59:59'\t"
354719c3dc6SMark de Wever            "%EX='23:59:59'\t"
355719c3dc6SMark de Wever            "%j='0'\t"
356719c3dc6SMark de Wever            "%Q='86399'\t"
357719c3dc6SMark de Wever            "%q='s'\t"
358719c3dc6SMark de Wever            "\n"),
359719c3dc6SMark de Wever         lfmt,
360719c3dc6SMark de Wever         23h + 59min + 59s);
361719c3dc6SMark de Wever 
362719c3dc6SMark de Wever   check(SV("%H='00'\t"
363719c3dc6SMark de Wever            "%OH='00'\t"
364719c3dc6SMark de Wever            "%I='12'\t"
365719c3dc6SMark de Wever            "%OI='12'\t"
366719c3dc6SMark de Wever            "%M='00'\t"
367719c3dc6SMark de Wever            "%OM='00'\t"
368719c3dc6SMark de Wever            "%S='00'\t"
369719c3dc6SMark de Wever            "%OS='00'\t"
370719c3dc6SMark de Wever #if defined(_AIX)
371719c3dc6SMark de Wever            "%p='AM'\t"
372719c3dc6SMark de Wever #else
373719c3dc6SMark de Wever            "%p=''\t"
374719c3dc6SMark de Wever #endif
375719c3dc6SMark de Wever            "%R='00:00'\t"
376719c3dc6SMark de Wever            "%T='00:00:00'\t"
377719c3dc6SMark de Wever #ifdef _WIN32
3781403080aSMark de Wever            "%r='00:00:00'\t"
379719c3dc6SMark de Wever #elif defined(_AIX)
380719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
3818f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
382719c3dc6SMark de Wever            "%r=''\t"
3831403080aSMark de Wever #elif defined(_WIN32)
3841403080aSMark de Wever            "%r='12:00:00'\t"
385719c3dc6SMark de Wever #else
386719c3dc6SMark de Wever            "%r='12:00:00 '\t"
387719c3dc6SMark de Wever #endif
388719c3dc6SMark de Wever            "%X='00:00:00'\t"
389719c3dc6SMark de Wever            "%EX='00:00:00'\t"
390719c3dc6SMark de Wever            "%j='7'\t"
391719c3dc6SMark de Wever            "%Q='7'\t"
392719c3dc6SMark de Wever            "%q='d'\t"
393719c3dc6SMark de Wever            "\n"),
394719c3dc6SMark de Wever         lfmt,
395719c3dc6SMark de Wever         std::chrono::duration<int, std::ratio<86400>>(7));
396719c3dc6SMark de Wever 
397719c3dc6SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
3988f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
399719c3dc6SMark de Wever   check(loc,
400719c3dc6SMark de Wever         SV("%H='00'\t"
401719c3dc6SMark de Wever            "%OH='00'\t"
402719c3dc6SMark de Wever            "%I='12'\t"
403719c3dc6SMark de Wever            "%OI='12'\t"
404719c3dc6SMark de Wever            "%M='00'\t"
405719c3dc6SMark de Wever            "%OM='00'\t"
406719c3dc6SMark de Wever            "%S='00'\t"
407719c3dc6SMark de Wever            "%OS='00'\t"
408719c3dc6SMark de Wever #  if defined(__APPLE__)
409719c3dc6SMark de Wever            "%p='AM'\t"
410719c3dc6SMark de Wever #  else
411719c3dc6SMark de Wever            "%p='午前'\t"
412719c3dc6SMark de Wever #  endif
413719c3dc6SMark de Wever            "%R='00:00'\t"
414719c3dc6SMark de Wever            "%T='00:00:00'\t"
4158f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
416719c3dc6SMark de Wever #    if defined(__APPLE__)
417719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
4188f01029bSMark de Wever #    else
4198f01029bSMark de Wever            "%r='12:00:00 午前'\t"
4208f01029bSMark de Wever #    endif
421719c3dc6SMark de Wever            "%X='00時00分00秒'\t"
422719c3dc6SMark de Wever            "%EX='00時00分00秒'\t"
4231403080aSMark de Wever #  elif defined(_WIN32)
4241403080aSMark de Wever            "%r='0:00:00'\t"
4251403080aSMark de Wever            "%X='0:00:00'\t"
4261403080aSMark de Wever            "%EX='0:00:00'\t"
427719c3dc6SMark de Wever #  else
428719c3dc6SMark de Wever            "%r='午前12:00:00'\t"
429719c3dc6SMark de Wever            "%X='00:00:00'\t"
430719c3dc6SMark de Wever            "%EX='00:00:00'\t"
431719c3dc6SMark de Wever #  endif
432719c3dc6SMark de Wever            "%j='0'\t"
433719c3dc6SMark de Wever            "%Q='0'\t"
434719c3dc6SMark de Wever            "%q='s'\t"
435719c3dc6SMark de Wever            "\n"),
436719c3dc6SMark de Wever         lfmt,
437719c3dc6SMark de Wever         0s);
438719c3dc6SMark de Wever 
439719c3dc6SMark de Wever   check(loc,
440719c3dc6SMark de Wever         SV("%H='11'\t"
441719c3dc6SMark de Wever            "%OH='11'\t"
442719c3dc6SMark de Wever            "%I='11'\t"
443719c3dc6SMark de Wever            "%OI='11'\t"
444719c3dc6SMark de Wever            "%M='59'\t"
445719c3dc6SMark de Wever            "%OM='59'\t"
446719c3dc6SMark de Wever            "%S='59'\t"
447719c3dc6SMark de Wever            "%OS='59'\t"
448719c3dc6SMark de Wever #  if defined(__APPLE__)
449719c3dc6SMark de Wever            "%p='AM'\t"
450719c3dc6SMark de Wever #  else
451719c3dc6SMark de Wever            "%p='午前'\t"
452719c3dc6SMark de Wever #  endif
453719c3dc6SMark de Wever            "%R='11:59'\t"
454719c3dc6SMark de Wever            "%T='11:59:59'\t"
4558f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
456719c3dc6SMark de Wever #    if defined(__APPLE__)
457719c3dc6SMark de Wever            "%r='11:59:59 AM'\t"
4588f01029bSMark de Wever #    else
4598f01029bSMark de Wever            "%r='11:59:59 午前'\t"
4608f01029bSMark de Wever #    endif
461719c3dc6SMark de Wever            "%X='11時59分59秒'\t"
462719c3dc6SMark de Wever            "%EX='11時59分59秒'\t"
4631403080aSMark de Wever #  elif defined(_WIN32)
4641403080aSMark de Wever            "%r='11:59:59'\t"
4651403080aSMark de Wever            "%X='11:59:59'\t"
4661403080aSMark de Wever            "%EX='11:59:59'\t"
467719c3dc6SMark de Wever #  else
468719c3dc6SMark de Wever            "%r='午前11:59:59'\t"
469719c3dc6SMark de Wever            "%X='11:59:59'\t"
470719c3dc6SMark de Wever            "%EX='11:59:59'\t"
471719c3dc6SMark de Wever #  endif
472719c3dc6SMark de Wever            "%j='0'\t"
473719c3dc6SMark de Wever            "%Q='43199'\t"
474719c3dc6SMark de Wever            "%q='s'\t"
475719c3dc6SMark de Wever            "\n"),
476719c3dc6SMark de Wever         lfmt,
477719c3dc6SMark de Wever         11h + 59min + 59s);
478719c3dc6SMark de Wever 
479719c3dc6SMark de Wever   check(loc,
480719c3dc6SMark de Wever         SV("%H='12'\t"
481719c3dc6SMark de Wever            "%OH='12'\t"
482719c3dc6SMark de Wever            "%I='12'\t"
483719c3dc6SMark de Wever            "%OI='12'\t"
484719c3dc6SMark de Wever            "%M='00'\t"
485719c3dc6SMark de Wever            "%OM='00'\t"
486719c3dc6SMark de Wever            "%S='00'\t"
487719c3dc6SMark de Wever            "%OS='00'\t"
488719c3dc6SMark de Wever #  if defined(__APPLE__)
489719c3dc6SMark de Wever            "%p='PM'\t"
490719c3dc6SMark de Wever #  else
491719c3dc6SMark de Wever            "%p='午後'\t"
492719c3dc6SMark de Wever #  endif
493719c3dc6SMark de Wever            "%R='12:00'\t"
494719c3dc6SMark de Wever            "%T='12:00:00'\t"
4958f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
496719c3dc6SMark de Wever #    if defined(__APPLE__)
497719c3dc6SMark de Wever            "%r='12:00:00 PM'\t"
4988f01029bSMark de Wever #    else
4998f01029bSMark de Wever            "%r='12:00:00 午後'\t"
5008f01029bSMark de Wever #    endif
501719c3dc6SMark de Wever            "%X='12時00分00秒'\t"
502719c3dc6SMark de Wever            "%EX='12時00分00秒'\t"
503719c3dc6SMark de Wever #  else
5041403080aSMark de Wever #    ifdef _WIN32
5051403080aSMark de Wever            "%r='12:00:00'\t"
5061403080aSMark de Wever #    else
507719c3dc6SMark de Wever            "%r='午後12:00:00'\t"
5081403080aSMark de Wever #    endif
509719c3dc6SMark de Wever            "%X='12:00:00'\t"
510719c3dc6SMark de Wever            "%EX='12:00:00'\t"
511719c3dc6SMark de Wever #  endif
512719c3dc6SMark de Wever            "%j='0'\t"
513719c3dc6SMark de Wever            "%Q='12'\t"
514719c3dc6SMark de Wever            "%q='h'\t"
515719c3dc6SMark de Wever            "\n"),
516719c3dc6SMark de Wever         lfmt,
517719c3dc6SMark de Wever         12h);
518719c3dc6SMark de Wever 
519719c3dc6SMark de Wever   check(loc,
520719c3dc6SMark de Wever         SV("%H='23'\t"
521719c3dc6SMark de Wever            "%OH='23'\t"
522719c3dc6SMark de Wever            "%I='11'\t"
523719c3dc6SMark de Wever            "%OI='11'\t"
524719c3dc6SMark de Wever            "%M='59'\t"
525719c3dc6SMark de Wever            "%OM='59'\t"
526719c3dc6SMark de Wever            "%S='59'\t"
527719c3dc6SMark de Wever            "%OS='59'\t"
528719c3dc6SMark de Wever #  if defined(__APPLE__)
529719c3dc6SMark de Wever            "%p='PM'\t"
530719c3dc6SMark de Wever #  else
531719c3dc6SMark de Wever            "%p='午後'\t"
532719c3dc6SMark de Wever #  endif
533719c3dc6SMark de Wever            "%R='23:59'\t"
534719c3dc6SMark de Wever            "%T='23:59:59'\t"
5358f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
536719c3dc6SMark de Wever #    if defined(__APPLE__)
537719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
5388f01029bSMark de Wever #    else
5398f01029bSMark de Wever            "%r='11:59:59 午後'\t"
5408f01029bSMark de Wever #    endif
541719c3dc6SMark de Wever            "%X='23時59分59秒'\t"
542719c3dc6SMark de Wever            "%EX='23時59分59秒'\t"
543719c3dc6SMark de Wever #  else
5441403080aSMark de Wever #    ifdef _WIN32
5451403080aSMark de Wever            "%r='23:59:59'\t"
5461403080aSMark de Wever #    else
547719c3dc6SMark de Wever            "%r='午後11:59:59'\t"
5481403080aSMark de Wever #    endif
549719c3dc6SMark de Wever            "%X='23:59:59'\t"
550719c3dc6SMark de Wever            "%EX='23:59:59'\t"
551719c3dc6SMark de Wever #  endif
552719c3dc6SMark de Wever            "%j='0'\t"
553719c3dc6SMark de Wever            "%Q='86399'\t"
554719c3dc6SMark de Wever            "%q='s'\t"
555719c3dc6SMark de Wever            "\n"),
556719c3dc6SMark de Wever         lfmt,
557719c3dc6SMark de Wever         23h + 59min + 59s);
558719c3dc6SMark de Wever 
559719c3dc6SMark de Wever   check(loc,
560719c3dc6SMark de Wever         SV("%H='00'\t"
561719c3dc6SMark de Wever            "%OH='00'\t"
562719c3dc6SMark de Wever            "%I='12'\t"
563719c3dc6SMark de Wever            "%OI='12'\t"
564719c3dc6SMark de Wever            "%M='00'\t"
565719c3dc6SMark de Wever            "%OM='00'\t"
566719c3dc6SMark de Wever            "%S='00'\t"
567719c3dc6SMark de Wever            "%OS='00'\t"
568719c3dc6SMark de Wever #  if defined(__APPLE__)
569719c3dc6SMark de Wever            "%p='AM'\t"
570719c3dc6SMark de Wever #  else
571719c3dc6SMark de Wever            "%p='午前'\t"
572719c3dc6SMark de Wever #  endif
573719c3dc6SMark de Wever            "%R='00:00'\t"
574719c3dc6SMark de Wever            "%T='00:00:00'\t"
5758f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
576719c3dc6SMark de Wever #    if defined(__APPLE__)
577719c3dc6SMark de Wever            "%r='12:00:00 AM'\t"
5788f01029bSMark de Wever #    else
5798f01029bSMark de Wever            "%r='12:00:00 午前'\t"
5808f01029bSMark de Wever #    endif
581719c3dc6SMark de Wever            "%X='00時00分00秒'\t"
582719c3dc6SMark de Wever            "%EX='00時00分00秒'\t"
5831403080aSMark de Wever #  elif defined(_WIN32)
5841403080aSMark de Wever            "%r='0:00:00'\t"
5851403080aSMark de Wever            "%X='0:00:00'\t"
5861403080aSMark de Wever            "%EX='0:00:00'\t"
587719c3dc6SMark de Wever #  else
588719c3dc6SMark de Wever            "%r='午前12:00:00'\t"
589719c3dc6SMark de Wever            "%X='00:00:00'\t"
590719c3dc6SMark de Wever            "%EX='00:00:00'\t"
591719c3dc6SMark de Wever #  endif
592719c3dc6SMark de Wever            "%j='7'\t"
593719c3dc6SMark de Wever            "%Q='7'\t"
594719c3dc6SMark de Wever            "%q='d'\t"
595719c3dc6SMark de Wever            "\n"),
596719c3dc6SMark de Wever         lfmt,
597719c3dc6SMark de Wever         std::chrono::duration<int, std::ratio<86400>>(7));
5981403080aSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
599719c3dc6SMark de Wever   check(loc,
600719c3dc6SMark de Wever         SV("%H='00'\t"
601719c3dc6SMark de Wever            "%OH='〇'\t"
602719c3dc6SMark de Wever            "%I='12'\t"
603719c3dc6SMark de Wever            "%OI='十二'\t"
604719c3dc6SMark de Wever            "%M='00'\t"
605719c3dc6SMark de Wever            "%OM='〇'\t"
606719c3dc6SMark de Wever            "%S='00'\t"
607719c3dc6SMark de Wever            "%OS='〇'\t"
608719c3dc6SMark de Wever            "%p='午前'\t"
609719c3dc6SMark de Wever            "%R='00:00'\t"
610719c3dc6SMark de Wever            "%T='00:00:00'\t"
611719c3dc6SMark de Wever            "%r='午前12時00分00秒'\t"
612719c3dc6SMark de Wever            "%X='00時00分00秒'\t"
613719c3dc6SMark de Wever            "%EX='00時00分00秒'\t"
614719c3dc6SMark de Wever            "%j='0'\t"
615719c3dc6SMark de Wever            "%Q='0'\t"
616719c3dc6SMark de Wever            "%q='s'\t"
617719c3dc6SMark de Wever            "\n"),
618719c3dc6SMark de Wever         lfmt,
619719c3dc6SMark de Wever         0s);
620719c3dc6SMark de Wever 
621719c3dc6SMark de Wever   check(loc,
622719c3dc6SMark de Wever         SV("%H='11'\t"
623719c3dc6SMark de Wever            "%OH='十一'\t"
624719c3dc6SMark de Wever            "%I='11'\t"
625719c3dc6SMark de Wever            "%OI='十一'\t"
626719c3dc6SMark de Wever            "%M='59'\t"
627719c3dc6SMark de Wever            "%OM='五十九'\t"
628719c3dc6SMark de Wever            "%S='59'\t"
629719c3dc6SMark de Wever            "%OS='五十九'\t"
630719c3dc6SMark de Wever            "%p='午前'\t"
631719c3dc6SMark de Wever            "%R='11:59'\t"
632719c3dc6SMark de Wever            "%T='11:59:59'\t"
633719c3dc6SMark de Wever            "%r='午前11時59分59秒'\t"
634719c3dc6SMark de Wever            "%X='11時59分59秒'\t"
635719c3dc6SMark de Wever            "%EX='11時59分59秒'\t"
636719c3dc6SMark de Wever            "%j='0'\t"
637719c3dc6SMark de Wever            "%Q='43199'\t"
638719c3dc6SMark de Wever            "%q='s'\t"
639719c3dc6SMark de Wever            "\n"),
640719c3dc6SMark de Wever         lfmt,
641719c3dc6SMark de Wever         11h + 59min + 59s);
642719c3dc6SMark de Wever 
643719c3dc6SMark de Wever   check(loc,
644719c3dc6SMark de Wever         SV("%H='12'\t"
645719c3dc6SMark de Wever            "%OH='十二'\t"
646719c3dc6SMark de Wever            "%I='12'\t"
647719c3dc6SMark de Wever            "%OI='十二'\t"
648719c3dc6SMark de Wever            "%M='00'\t"
649719c3dc6SMark de Wever            "%OM='〇'\t"
650719c3dc6SMark de Wever            "%S='00'\t"
651719c3dc6SMark de Wever            "%OS='〇'\t"
652719c3dc6SMark de Wever            "%p='午後'\t"
653719c3dc6SMark de Wever            "%R='12:00'\t"
654719c3dc6SMark de Wever            "%T='12:00:00'\t"
655719c3dc6SMark de Wever            "%r='午後12時00分00秒'\t"
656719c3dc6SMark de Wever            "%X='12時00分00秒'\t"
657719c3dc6SMark de Wever            "%EX='12時00分00秒'\t"
658719c3dc6SMark de Wever            "%j='0'\t"
659719c3dc6SMark de Wever            "%Q='12'\t"
660719c3dc6SMark de Wever            "%q='h'\t"
661719c3dc6SMark de Wever            "\n"),
662719c3dc6SMark de Wever         lfmt,
663719c3dc6SMark de Wever         12h);
664719c3dc6SMark de Wever 
665719c3dc6SMark de Wever   check(loc,
666719c3dc6SMark de Wever         SV("%H='23'\t"
667719c3dc6SMark de Wever            "%OH='二十三'\t"
668719c3dc6SMark de Wever            "%I='11'\t"
669719c3dc6SMark de Wever            "%OI='十一'\t"
670719c3dc6SMark de Wever            "%M='59'\t"
671719c3dc6SMark de Wever            "%OM='五十九'\t"
672719c3dc6SMark de Wever            "%S='59'\t"
673719c3dc6SMark de Wever            "%OS='五十九'\t"
674719c3dc6SMark de Wever            "%p='午後'\t"
675719c3dc6SMark de Wever            "%R='23:59'\t"
676719c3dc6SMark de Wever            "%T='23:59:59'\t"
677719c3dc6SMark de Wever            "%r='午後11時59分59秒'\t"
678719c3dc6SMark de Wever            "%X='23時59分59秒'\t"
679719c3dc6SMark de Wever            "%EX='23時59分59秒'\t"
680719c3dc6SMark de Wever            "%j='0'\t"
681719c3dc6SMark de Wever            "%Q='86399'\t"
682719c3dc6SMark de Wever            "%q='s'\t"
683719c3dc6SMark de Wever            "\n"),
684719c3dc6SMark de Wever         lfmt,
685719c3dc6SMark de Wever         23h + 59min + 59s);
686719c3dc6SMark de Wever 
687719c3dc6SMark de Wever   check(loc,
688719c3dc6SMark de Wever         SV("%H='00'\t"
689719c3dc6SMark de Wever            "%OH='〇'\t"
690719c3dc6SMark de Wever            "%I='12'\t"
691719c3dc6SMark de Wever            "%OI='十二'\t"
692719c3dc6SMark de Wever            "%M='00'\t"
693719c3dc6SMark de Wever            "%OM='〇'\t"
694719c3dc6SMark de Wever            "%S='00'\t"
695719c3dc6SMark de Wever            "%OS='〇'\t"
696719c3dc6SMark de Wever            "%p='午前'\t"
697719c3dc6SMark de Wever            "%R='00:00'\t"
698719c3dc6SMark de Wever            "%T='00:00:00'\t"
699719c3dc6SMark de Wever            "%r='午前12時00分00秒'\t"
700719c3dc6SMark de Wever            "%X='00時00分00秒'\t"
701719c3dc6SMark de Wever            "%EX='00時00分00秒'\t"
702719c3dc6SMark de Wever            "%j='7'\t"
703719c3dc6SMark de Wever            "%Q='7'\t"
704719c3dc6SMark de Wever            "%q='d'\t"
705719c3dc6SMark de Wever            "\n"),
706719c3dc6SMark de Wever         lfmt,
707719c3dc6SMark de Wever         std::chrono::duration<int, std::ratio<86400>>(7));
7081403080aSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)
709719c3dc6SMark de Wever 
710719c3dc6SMark de Wever   std::locale::global(std::locale::classic());
711719c3dc6SMark de Wever }
712719c3dc6SMark de Wever 
713719c3dc6SMark de Wever template <class CharT>
714719c3dc6SMark de Wever static void test_valid_negative_integral_values() {
715719c3dc6SMark de Wever   // [time.format]/4 The result of formatting a std::chrono::duration instance
716719c3dc6SMark de Wever   // holding a negative value, or an hh_mm_ss object h for which
717719c3dc6SMark de Wever   // h.is_negative() is true, is equivalent to the output of the corresponding
718719c3dc6SMark de Wever   // positive value, with a STATICALLY-WIDEN<charT>("-") character sequence
719719c3dc6SMark de Wever   // placed before the replacement of the initial conversion specifier.
720719c3dc6SMark de Wever   //
721719c3dc6SMark de Wever   // Note in this case %% is the initial conversion specifier.
722719c3dc6SMark de Wever   using namespace std::literals::chrono_literals;
723719c3dc6SMark de Wever 
724719c3dc6SMark de Wever   constexpr std::basic_string_view<CharT> fmt = SV(
725719c3dc6SMark de Wever       "{:"
726719c3dc6SMark de Wever       "%%H='%H'%t"
727719c3dc6SMark de Wever       "%%OH='%OH'%t"
728719c3dc6SMark de Wever       "%%I='%I'%t"
729719c3dc6SMark de Wever       "%%OI='%OI'%t"
730719c3dc6SMark de Wever       "%%M='%M'%t"
731719c3dc6SMark de Wever       "%%OM='%OM'%t"
732719c3dc6SMark de Wever       "%%S='%S'%t"
733719c3dc6SMark de Wever       "%%OS='%OS'%t"
734719c3dc6SMark de Wever       "%%p='%p'%t"
735719c3dc6SMark de Wever       "%%R='%R'%t"
736719c3dc6SMark de Wever       "%%T='%T'%t"
737719c3dc6SMark de Wever       "%%r='%r'%t"
738719c3dc6SMark de Wever       "%%X='%X'%t"
739719c3dc6SMark de Wever       "%%EX='%EX'%t"
740719c3dc6SMark de Wever       "%%j='%j'%t"
741719c3dc6SMark de Wever       "%%Q='%Q'%t"
742719c3dc6SMark de Wever       "%%q='%q'%t"
743719c3dc6SMark de Wever       "%n}");
744719c3dc6SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV(
745719c3dc6SMark de Wever       "{:L"
746719c3dc6SMark de Wever       "%%H='%H'%t"
747719c3dc6SMark de Wever       "%%OH='%OH'%t"
748719c3dc6SMark de Wever       "%%I='%I'%t"
749719c3dc6SMark de Wever       "%%OI='%OI'%t"
750719c3dc6SMark de Wever       "%%M='%M'%t"
751719c3dc6SMark de Wever       "%%OM='%OM'%t"
752719c3dc6SMark de Wever       "%%S='%S'%t"
753719c3dc6SMark de Wever       "%%OS='%OS'%t"
754719c3dc6SMark de Wever       "%%p='%p'%t"
755719c3dc6SMark de Wever       "%%R='%R'%t"
756719c3dc6SMark de Wever       "%%T='%T'%t"
757719c3dc6SMark de Wever       "%%r='%r'%t"
758719c3dc6SMark de Wever       "%%X='%X'%t"
759719c3dc6SMark de Wever       "%%EX='%EX'%t"
760719c3dc6SMark de Wever       "%%j='%j'%t"
761719c3dc6SMark de Wever       "%%Q='%Q'%t"
762719c3dc6SMark de Wever       "%%q='%q'%t"
763719c3dc6SMark de Wever       "%n}");
764719c3dc6SMark de Wever 
765719c3dc6SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
766719c3dc6SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
767719c3dc6SMark de Wever 
768719c3dc6SMark de Wever   // Non localized output using C-locale
769719c3dc6SMark de Wever   check(SV("-%H='23'\t"
770719c3dc6SMark de Wever            "%OH='23'\t"
771719c3dc6SMark de Wever            "%I='11'\t"
772719c3dc6SMark de Wever            "%OI='11'\t"
773719c3dc6SMark de Wever            "%M='59'\t"
774719c3dc6SMark de Wever            "%OM='59'\t"
775719c3dc6SMark de Wever            "%S='59'\t"
776719c3dc6SMark de Wever            "%OS='59'\t"
777719c3dc6SMark de Wever            "%p='PM'\t"
778719c3dc6SMark de Wever            "%R='23:59'\t"
779719c3dc6SMark de Wever            "%T='23:59:59'\t"
780719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
781719c3dc6SMark de Wever            "%X='23:59:59'\t"
782719c3dc6SMark de Wever            "%EX='23:59:59'\t"
783719c3dc6SMark de Wever            "%j='0'\t"
784719c3dc6SMark de Wever            "%Q='86399'\t"
785719c3dc6SMark de Wever            "%q='s'\t"
786719c3dc6SMark de Wever            "\n"),
787719c3dc6SMark de Wever         fmt,
788719c3dc6SMark de Wever         -(23h + 59min + 59s));
789719c3dc6SMark de Wever 
790719c3dc6SMark de Wever   // Use the global locale (fr_FR)
791719c3dc6SMark de Wever   check(SV("-%H='23'\t"
792719c3dc6SMark de Wever            "%OH='23'\t"
793719c3dc6SMark de Wever            "%I='11'\t"
794719c3dc6SMark de Wever            "%OI='11'\t"
795719c3dc6SMark de Wever            "%M='59'\t"
796719c3dc6SMark de Wever            "%OM='59'\t"
797719c3dc6SMark de Wever            "%S='59'\t"
798719c3dc6SMark de Wever            "%OS='59'\t"
799719c3dc6SMark de Wever #if defined(_AIX)
800719c3dc6SMark de Wever            "%p='PM'\t"
801719c3dc6SMark de Wever #else
802719c3dc6SMark de Wever            "%p=''\t"
803719c3dc6SMark de Wever #endif
804719c3dc6SMark de Wever            "%R='23:59'\t"
805719c3dc6SMark de Wever            "%T='23:59:59'\t"
806719c3dc6SMark de Wever #if defined(_AIX)
807719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
8088f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
809719c3dc6SMark de Wever            "%r=''\t"
8101403080aSMark de Wever #elif defined(_WIN32)
8111403080aSMark de Wever            "%r='23:59:59'\t"
812719c3dc6SMark de Wever #else
813719c3dc6SMark de Wever            "%r='11:59:59 '\t"
814719c3dc6SMark de Wever #endif
815719c3dc6SMark de Wever            "%X='23:59:59'\t"
816719c3dc6SMark de Wever            "%EX='23:59:59'\t"
817719c3dc6SMark de Wever            "%j='0'\t"
818719c3dc6SMark de Wever            "%Q='86399'\t"
819719c3dc6SMark de Wever            "%q='s'\t"
820719c3dc6SMark de Wever            "\n"),
821719c3dc6SMark de Wever         lfmt,
822719c3dc6SMark de Wever         -(23h + 59min + 59s));
823719c3dc6SMark de Wever 
824719c3dc6SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
8258f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
826719c3dc6SMark de Wever   check(loc,
827719c3dc6SMark de Wever         SV("-%H='23'\t"
828719c3dc6SMark de Wever            "%OH='23'\t"
829719c3dc6SMark de Wever            "%I='11'\t"
830719c3dc6SMark de Wever            "%OI='11'\t"
831719c3dc6SMark de Wever            "%M='59'\t"
832719c3dc6SMark de Wever            "%OM='59'\t"
833719c3dc6SMark de Wever            "%S='59'\t"
834719c3dc6SMark de Wever            "%OS='59'\t"
835719c3dc6SMark de Wever #  if defined(__APPLE__)
836719c3dc6SMark de Wever            "%p='PM'\t"
837719c3dc6SMark de Wever #  else
838719c3dc6SMark de Wever            "%p='午後'\t"
839719c3dc6SMark de Wever #  endif
840719c3dc6SMark de Wever            "%R='23:59'\t"
841719c3dc6SMark de Wever            "%T='23:59:59'\t"
8428f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
843719c3dc6SMark de Wever #    if defined(__APPLE__)
844719c3dc6SMark de Wever            "%r='11:59:59 PM'\t"
8458f01029bSMark de Wever #    else
8468f01029bSMark de Wever            "%r='11:59:59 午後'\t"
8478f01029bSMark de Wever #    endif
848719c3dc6SMark de Wever            "%X='23時59分59秒'\t"
849719c3dc6SMark de Wever            "%EX='23時59分59秒'\t"
8501403080aSMark de Wever #  elif defined(_WIN32)
8511403080aSMark de Wever            "%r='23:59:59'\t"
8521403080aSMark de Wever            "%X='23:59:59'\t"
8531403080aSMark de Wever            "%EX='23:59:59'\t"
854719c3dc6SMark de Wever #  else
855719c3dc6SMark de Wever            "%r='午後11:59:59'\t"
856719c3dc6SMark de Wever            "%X='23:59:59'\t"
857719c3dc6SMark de Wever            "%EX='23:59:59'\t"
858719c3dc6SMark de Wever #  endif
859719c3dc6SMark de Wever            "%j='0'\t"
860719c3dc6SMark de Wever            "%Q='86399'\t"
861719c3dc6SMark de Wever            "%q='s'\t"
862719c3dc6SMark de Wever            "\n"),
863719c3dc6SMark de Wever         lfmt,
864719c3dc6SMark de Wever         -(23h + 59min + 59s));
8658f01029bSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
866719c3dc6SMark de Wever   check(loc,
867719c3dc6SMark de Wever         SV("-%H='23'\t"
868719c3dc6SMark de Wever            "%OH='二十三'\t"
869719c3dc6SMark de Wever            "%I='11'\t"
870719c3dc6SMark de Wever            "%OI='十一'\t"
871719c3dc6SMark de Wever            "%M='59'\t"
872719c3dc6SMark de Wever            "%OM='五十九'\t"
873719c3dc6SMark de Wever            "%S='59'\t"
874719c3dc6SMark de Wever            "%OS='五十九'\t"
875719c3dc6SMark de Wever            "%p='午後'\t"
876719c3dc6SMark de Wever            "%R='23:59'\t"
877719c3dc6SMark de Wever            "%T='23:59:59'\t"
878719c3dc6SMark de Wever            "%r='午後11時59分59秒'\t"
879719c3dc6SMark de Wever            "%X='23時59分59秒'\t"
880719c3dc6SMark de Wever            "%EX='23時59分59秒'\t"
881719c3dc6SMark de Wever            "%j='0'\t"
882719c3dc6SMark de Wever            "%Q='86399'\t"
883719c3dc6SMark de Wever            "%q='s'\t"
884719c3dc6SMark de Wever            "\n"),
885719c3dc6SMark de Wever         lfmt,
886719c3dc6SMark de Wever         -(23h + 59min + 59s));
8878f01029bSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
888719c3dc6SMark de Wever   std::locale::global(std::locale::classic());
889719c3dc6SMark de Wever }
890719c3dc6SMark de Wever 
891719c3dc6SMark de Wever template <class CharT>
892719c3dc6SMark de Wever static void test_valid_fractional_values() {
893719c3dc6SMark de Wever   using namespace std::literals::chrono_literals;
894719c3dc6SMark de Wever 
895719c3dc6SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
896719c3dc6SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
897719c3dc6SMark de Wever 
898719c3dc6SMark de Wever   // Non localized output using C-locale
899719c3dc6SMark de Wever   check(SV("00.000000001"), SV("{:%S}"), 1ns);
900719c3dc6SMark de Wever   check(SV("00.000000501"), SV("{:%S}"), 501ns);
901719c3dc6SMark de Wever   check(SV("00.000001000"), SV("{:%S}"), 1000ns);
902719c3dc6SMark de Wever   check(SV("00.000000000001"), SV("{:%S}"), std::chrono::duration<int, std::pico>(1));
903719c3dc6SMark de Wever   check(SV("00.000000000000001"), SV("{:%S}"), std::chrono::duration<int, std::femto>(1));
904719c3dc6SMark de Wever   check(SV("00.000000000000000001"), SV("{:%S}"), std::chrono::duration<int, std::atto>(1));
905719c3dc6SMark de Wever 
906719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%S}"), 1ms);
907719c3dc6SMark de Wever   check(SV("00.01"), SV("{:%S}"), std::chrono::duration<int, std::centi>(1));
908719c3dc6SMark de Wever   check(SV("00.1"), SV("{:%S}"), std::chrono::duration<int, std::deci>(1));
909719c3dc6SMark de Wever   check(SV("01.1"), SV("{:%S}"), std::chrono::duration<int, std::deci>(11));
910719c3dc6SMark de Wever 
911719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%S}"), std::chrono::duration<float, std::milli>(1.123456789));
912719c3dc6SMark de Wever   check(SV("00.011"), SV("{:%S}"), std::chrono::duration<double, std::milli>(11.123456789));
913719c3dc6SMark de Wever   check(SV("01"), SV("{:%S}"), std::chrono::duration<long double>(61.123456789));
914719c3dc6SMark de Wever 
915719c3dc6SMark de Wever   check(SV("00.000000001"), SV("{:%OS}"), 1ns);
916719c3dc6SMark de Wever   check(SV("00.000000501"), SV("{:%OS}"), 501ns);
917719c3dc6SMark de Wever   check(SV("00.000001000"), SV("{:%OS}"), 1000ns);
918719c3dc6SMark de Wever   check(SV("00.000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::pico>(1));
919719c3dc6SMark de Wever   check(SV("00.000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::femto>(1));
920719c3dc6SMark de Wever   check(SV("00.000000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::atto>(1));
921719c3dc6SMark de Wever 
922719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%OS}"), 1ms);
923719c3dc6SMark de Wever   check(SV("00.01"), SV("{:%OS}"), std::chrono::duration<int, std::centi>(1));
924719c3dc6SMark de Wever   check(SV("00.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(1));
925719c3dc6SMark de Wever   check(SV("01.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(11));
926719c3dc6SMark de Wever 
927719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
928719c3dc6SMark de Wever   check(SV("00.011"), SV("{:%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
929719c3dc6SMark de Wever   check(SV("01"), SV("{:%OS}"), std::chrono::duration<long double>(61.123456789));
930719c3dc6SMark de Wever 
931719c3dc6SMark de Wever   check(SV("01:05:06.000000001"), SV("{:%T}"), 1h + 5min + 6s + 1ns);
932719c3dc6SMark de Wever   check(SV("01:05:06.000000501"), SV("{:%T}"), 1h + 5min + 6s + 501ns);
933719c3dc6SMark de Wever   check(SV("01:05:06.000001000"), SV("{:%T}"), 1h + 5min + 6s + 1000ns);
934719c3dc6SMark de Wever 
935719c3dc6SMark de Wever   check(SV("01:05:06.001"), SV("{:%T}"), 1h + 5min + 6s + 1ms);
936719c3dc6SMark de Wever   check(SV("01:05:06.01"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
937719c3dc6SMark de Wever   check(SV("01:05:06.1"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
938719c3dc6SMark de Wever   check(SV("01:05:07.1"), SV("{:%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
939719c3dc6SMark de Wever 
940719c3dc6SMark de Wever   check(
941719c3dc6SMark de Wever       SV("00:01:02"), SV("{:%T}"), std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
942719c3dc6SMark de Wever   check(SV("01:05:11"),
943719c3dc6SMark de Wever         SV("{:%T}"),
944719c3dc6SMark de Wever         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
945719c3dc6SMark de Wever             std::chrono::duration<double>(11.123456789));
946719c3dc6SMark de Wever   check(SV("01:06:01"),
947719c3dc6SMark de Wever         SV("{:%T}"),
948719c3dc6SMark de Wever         std::chrono::duration<long double, std::ratio<3600>>(1) +
949719c3dc6SMark de Wever             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
950719c3dc6SMark de Wever 
951719c3dc6SMark de Wever   check(SV("0"), SV("{:%j}"), std::chrono::duration<float, std::milli>(1.));
952719c3dc6SMark de Wever   check(SV("1"), SV("{:%j}"), std::chrono::duration<double, std::milli>(86'400'000));
953719c3dc6SMark de Wever   check(SV("1"), SV("{:%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
954719c3dc6SMark de Wever 
955719c3dc6SMark de Wever   check(SV("1000000"), SV("{:%Q}"), 1'000'000s);
956719c3dc6SMark de Wever   check(SV("1"), SV("{:%Q}"), std::chrono::duration<float, std::milli>(1.));
957719c3dc6SMark de Wever   check(SV("1.123456789"), SV("{:.6%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
958719c3dc6SMark de Wever   check(SV("1.123456789"), SV("{:.9%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
959719c3dc6SMark de Wever 
960719c3dc6SMark de Wever   // Use the global locale (fr_FR)
961719c3dc6SMark de Wever   check(SV("00,000000001"), SV("{:L%S}"), 1ns);
962719c3dc6SMark de Wever   check(SV("00,000000501"), SV("{:L%S}"), 501ns);
963719c3dc6SMark de Wever   check(SV("00,000001000"), SV("{:L%S}"), 1000ns);
964719c3dc6SMark de Wever   check(SV("00,000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::pico>(1));
965719c3dc6SMark de Wever   check(SV("00,000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::femto>(1));
966719c3dc6SMark de Wever   check(SV("00,000000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::atto>(1));
967719c3dc6SMark de Wever 
968719c3dc6SMark de Wever   check(SV("00,001"), SV("{:L%S}"), 1ms);
969719c3dc6SMark de Wever   check(SV("00,01"), SV("{:L%S}"), std::chrono::duration<int, std::centi>(1));
970719c3dc6SMark de Wever   check(SV("00,1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(1));
971719c3dc6SMark de Wever   check(SV("01,1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(11));
972719c3dc6SMark de Wever 
973719c3dc6SMark de Wever   check(SV("00,001"), SV("{:L%S}"), std::chrono::duration<float, std::milli>(1.123456789));
974719c3dc6SMark de Wever   check(SV("00,011"), SV("{:L%S}"), std::chrono::duration<double, std::milli>(11.123456789));
975719c3dc6SMark de Wever   check(SV("01"), SV("{:L%S}"), std::chrono::duration<long double>(61.123456789));
976719c3dc6SMark de Wever 
977719c3dc6SMark de Wever   check(SV("00,000000001"), SV("{:L%OS}"), 1ns);
978719c3dc6SMark de Wever   check(SV("00,000000501"), SV("{:L%OS}"), 501ns);
979719c3dc6SMark de Wever   check(SV("00,000001000"), SV("{:L%OS}"), 1000ns);
980719c3dc6SMark de Wever   check(SV("00,000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::pico>(1));
981719c3dc6SMark de Wever   check(SV("00,000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::femto>(1));
982719c3dc6SMark de Wever   check(SV("00,000000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::atto>(1));
983719c3dc6SMark de Wever 
984719c3dc6SMark de Wever   check(SV("00,001"), SV("{:L%OS}"), 1ms);
985719c3dc6SMark de Wever   check(SV("00,01"), SV("{:L%OS}"), std::chrono::duration<int, std::centi>(1));
986719c3dc6SMark de Wever   check(SV("00,1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(1));
987719c3dc6SMark de Wever   check(SV("01,1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(11));
988719c3dc6SMark de Wever 
989719c3dc6SMark de Wever   check(SV("00,001"), SV("{:L%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
990719c3dc6SMark de Wever   check(SV("00,011"), SV("{:L%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
991719c3dc6SMark de Wever   check(SV("01"), SV("{:L%OS}"), std::chrono::duration<long double>(61.123456789));
992719c3dc6SMark de Wever 
993719c3dc6SMark de Wever   check(SV("01:05:06,000000001"), SV("{:L%T}"), 1h + 5min + 6s + 1ns);
994719c3dc6SMark de Wever   check(SV("01:05:06,000000501"), SV("{:L%T}"), 1h + 5min + 6s + 501ns);
995719c3dc6SMark de Wever   check(SV("01:05:06,000001000"), SV("{:L%T}"), 1h + 5min + 6s + 1000ns);
996719c3dc6SMark de Wever 
997719c3dc6SMark de Wever   check(SV("01:05:06,001"), SV("{:L%T}"), 1h + 5min + 6s + 1ms);
998719c3dc6SMark de Wever   check(SV("01:05:06,01"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
999719c3dc6SMark de Wever   check(SV("01:05:06,1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
1000719c3dc6SMark de Wever   check(SV("01:05:07,1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
1001719c3dc6SMark de Wever 
1002719c3dc6SMark de Wever   check(SV("00:01:02"),
1003719c3dc6SMark de Wever         SV("{:L%T}"),
1004719c3dc6SMark de Wever         std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
1005719c3dc6SMark de Wever   check(SV("01:05:11"),
1006719c3dc6SMark de Wever         SV("{:L%T}"),
1007719c3dc6SMark de Wever         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
1008719c3dc6SMark de Wever             std::chrono::duration<double>(11.123456789));
1009719c3dc6SMark de Wever   check(SV("01:06:01"),
1010719c3dc6SMark de Wever         SV("{:L%T}"),
1011719c3dc6SMark de Wever         std::chrono::duration<long double, std::ratio<3600>>(1) +
1012719c3dc6SMark de Wever             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
1013719c3dc6SMark de Wever 
1014719c3dc6SMark de Wever   check(SV("0"), SV("{:L%j}"), std::chrono::duration<float, std::milli>(1.));
1015719c3dc6SMark de Wever   check(SV("1"), SV("{:L%j}"), std::chrono::duration<double, std::milli>(86'400'000));
1016719c3dc6SMark de Wever   check(SV("1"), SV("{:L%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
1017719c3dc6SMark de Wever 
1018719c3dc6SMark de Wever   check(SV("1000000"), SV("{:L%Q}"), 1'000'000s); // The Standard mandates not localized.
1019719c3dc6SMark de Wever   check(SV("1"), SV("{:L%Q}"), std::chrono::duration<float, std::milli>(1.));
1020719c3dc6SMark de Wever   check(SV("1.123456789"), SV("{:.6L%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
1021719c3dc6SMark de Wever   check(SV("1.123456789"), SV("{:.9L%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
1022719c3dc6SMark de Wever 
1023719c3dc6SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
1024719c3dc6SMark de Wever   check(loc, SV("00.000000001"), SV("{:L%S}"), 1ns);
1025719c3dc6SMark de Wever   check(loc, SV("00.000000501"), SV("{:L%S}"), 501ns);
1026719c3dc6SMark de Wever   check(loc, SV("00.000001000"), SV("{:L%S}"), 1000ns);
1027719c3dc6SMark de Wever   check(loc, SV("00.000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::pico>(1));
1028719c3dc6SMark de Wever   check(loc, SV("00.000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::femto>(1));
1029719c3dc6SMark de Wever   check(loc, SV("00.000000000000000001"), SV("{:L%S}"), std::chrono::duration<int, std::atto>(1));
1030719c3dc6SMark de Wever 
1031719c3dc6SMark de Wever   check(loc, SV("00.001"), SV("{:L%S}"), 1ms);
1032719c3dc6SMark de Wever   check(loc, SV("00.01"), SV("{:L%S}"), std::chrono::duration<int, std::centi>(1));
1033719c3dc6SMark de Wever   check(loc, SV("00.1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(1));
1034719c3dc6SMark de Wever   check(loc, SV("01.1"), SV("{:L%S}"), std::chrono::duration<int, std::deci>(11));
1035719c3dc6SMark de Wever 
1036719c3dc6SMark de Wever   check(loc, SV("00.001"), SV("{:L%S}"), std::chrono::duration<float, std::milli>(1.123456789));
1037719c3dc6SMark de Wever   check(loc, SV("00.011"), SV("{:L%S}"), std::chrono::duration<double, std::milli>(11.123456789));
1038719c3dc6SMark de Wever   check(loc, SV("01"), SV("{:L%S}"), std::chrono::duration<long double>(61.123456789));
1039719c3dc6SMark de Wever 
10408f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
10418f01029bSMark de Wever 
1042719c3dc6SMark de Wever   check(SV("00.000000001"), SV("{:%OS}"), 1ns);
1043719c3dc6SMark de Wever   check(SV("00.000000501"), SV("{:%OS}"), 501ns);
1044719c3dc6SMark de Wever   check(SV("00.000001000"), SV("{:%OS}"), 1000ns);
1045719c3dc6SMark de Wever   check(SV("00.000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::pico>(1));
1046719c3dc6SMark de Wever   check(SV("00.000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::femto>(1));
1047719c3dc6SMark de Wever   check(SV("00.000000000000000001"), SV("{:%OS}"), std::chrono::duration<int, std::atto>(1));
1048719c3dc6SMark de Wever 
1049719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%OS}"), 1ms);
1050719c3dc6SMark de Wever   check(SV("00.01"), SV("{:%OS}"), std::chrono::duration<int, std::centi>(1));
1051719c3dc6SMark de Wever   check(SV("00.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(1));
1052719c3dc6SMark de Wever   check(SV("01.1"), SV("{:%OS}"), std::chrono::duration<int, std::deci>(11));
1053719c3dc6SMark de Wever 
1054719c3dc6SMark de Wever   check(SV("00.001"), SV("{:%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
1055719c3dc6SMark de Wever   check(SV("00.011"), SV("{:%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
1056719c3dc6SMark de Wever   check(SV("01"), SV("{:%OS}"), std::chrono::duration<long double>(61.123456789));
10578f01029bSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
10588f01029bSMark de Wever 
1059719c3dc6SMark de Wever   check(loc, SV("〇.000000001"), SV("{:L%OS}"), 1ns);
1060719c3dc6SMark de Wever   check(loc, SV("〇.000000501"), SV("{:L%OS}"), 501ns);
1061719c3dc6SMark de Wever   check(loc, SV("〇.000001000"), SV("{:L%OS}"), 1000ns);
1062719c3dc6SMark de Wever   check(loc, SV("〇.000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::pico>(1));
1063719c3dc6SMark de Wever   check(loc, SV("〇.000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::femto>(1));
1064719c3dc6SMark de Wever   check(loc, SV("〇.000000000000000001"), SV("{:L%OS}"), std::chrono::duration<int, std::atto>(1));
1065719c3dc6SMark de Wever 
1066719c3dc6SMark de Wever   check(loc, SV("〇.001"), SV("{:L%OS}"), 1ms);
1067719c3dc6SMark de Wever   check(loc, SV("〇.01"), SV("{:L%OS}"), std::chrono::duration<int, std::centi>(1));
1068719c3dc6SMark de Wever   check(loc, SV("〇.1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(1));
1069719c3dc6SMark de Wever   check(loc, SV("一.1"), SV("{:L%OS}"), std::chrono::duration<int, std::deci>(11));
1070719c3dc6SMark de Wever 
1071719c3dc6SMark de Wever   check(loc, SV("〇.001"), SV("{:L%OS}"), std::chrono::duration<float, std::milli>(1.123456789));
1072719c3dc6SMark de Wever   check(loc, SV("〇.011"), SV("{:L%OS}"), std::chrono::duration<double, std::milli>(11.123456789));
1073719c3dc6SMark de Wever   check(loc, SV("一"), SV("{:L%OS}"), std::chrono::duration<long double>(61.123456789));
10748f01029bSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32)|| defined(__FreeBSD__)
1075719c3dc6SMark de Wever 
1076719c3dc6SMark de Wever   check(loc, SV("01:05:06.000000001"), SV("{:L%T}"), 1h + 5min + 6s + 1ns);
1077719c3dc6SMark de Wever   check(loc, SV("01:05:06.000000501"), SV("{:L%T}"), 1h + 5min + 6s + 501ns);
1078719c3dc6SMark de Wever   check(loc, SV("01:05:06.000001000"), SV("{:L%T}"), 1h + 5min + 6s + 1000ns);
1079719c3dc6SMark de Wever 
1080719c3dc6SMark de Wever   check(loc, SV("01:05:06.001"), SV("{:L%T}"), 1h + 5min + 6s + 1ms);
1081719c3dc6SMark de Wever   check(loc, SV("01:05:06.01"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::centi>(1));
1082719c3dc6SMark de Wever   check(loc, SV("01:05:06.1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(1));
1083719c3dc6SMark de Wever   check(loc, SV("01:05:07.1"), SV("{:L%T}"), 1h + 5min + 6s + std::chrono::duration<int, std::deci>(11));
1084719c3dc6SMark de Wever 
1085719c3dc6SMark de Wever   check(loc,
1086719c3dc6SMark de Wever         SV("00:01:02"),
1087719c3dc6SMark de Wever         SV("{:L%T}"),
1088719c3dc6SMark de Wever         std::chrono::duration<float, std::ratio<60>>(1) + std::chrono::duration<float>(2.5));
1089719c3dc6SMark de Wever   check(loc,
1090719c3dc6SMark de Wever         SV("01:05:11"),
1091719c3dc6SMark de Wever         SV("{:L%T}"),
1092719c3dc6SMark de Wever         std::chrono::duration<double, std::ratio<3600>>(1) + std::chrono::duration<double, std::ratio<60>>(5) +
1093719c3dc6SMark de Wever             std::chrono::duration<double>(11.123456789));
1094719c3dc6SMark de Wever   check(loc,
1095719c3dc6SMark de Wever         SV("01:06:01"),
1096719c3dc6SMark de Wever         SV("{:L%T}"),
1097719c3dc6SMark de Wever         std::chrono::duration<long double, std::ratio<3600>>(1) +
1098719c3dc6SMark de Wever             std::chrono::duration<long double, std::ratio<60>>(5) + std::chrono::duration<long double>(61.123456789));
1099719c3dc6SMark de Wever 
1100719c3dc6SMark de Wever   check(loc, SV("0"), SV("{:L%j}"), std::chrono::duration<float, std::milli>(1.));
1101719c3dc6SMark de Wever   check(loc, SV("1"), SV("{:L%j}"), std::chrono::duration<double, std::milli>(86'400'000));
1102719c3dc6SMark de Wever   check(loc, SV("1"), SV("{:L%j}"), std::chrono::duration<long double, std::ratio<7 * 24 * 3600>>(0.14285714286));
1103719c3dc6SMark de Wever 
1104719c3dc6SMark de Wever   check(loc, SV("1000000"), SV("{:L%Q}"), 1'000'000s); // The Standard mandates not localized.
1105719c3dc6SMark de Wever   check(loc, SV("1"), SV("{:L%Q}"), std::chrono::duration<float, std::milli>(1.));
1106719c3dc6SMark de Wever   check(loc, SV("1.123456789"), SV("{:.6L%Q}"), std::chrono::duration<double, std::milli>(1.123456789));
1107719c3dc6SMark de Wever   check(loc, SV("1.123456789"), SV("{:.9L%Q}"), std::chrono::duration<long double, std::milli>(1.123456789));
1108719c3dc6SMark de Wever 
1109719c3dc6SMark de Wever   std::locale::global(std::locale::classic());
1110719c3dc6SMark de Wever }
1111719c3dc6SMark de Wever 
1112719c3dc6SMark de Wever template <class CharT>
1113719c3dc6SMark de Wever static void test_valid_values() {
1114719c3dc6SMark de Wever   test_valid_positive_integral_values<CharT>();
1115719c3dc6SMark de Wever   test_valid_negative_integral_values<CharT>();
1116719c3dc6SMark de Wever   test_valid_fractional_values<CharT>();
1117719c3dc6SMark de Wever }
1118719c3dc6SMark de Wever 
1119719c3dc6SMark de Wever template <class CharT>
112028584755SMark de Wever static void test_pr62082() {
112128584755SMark de Wever   // Examples in https://llvm.org/PR62082
112228584755SMark de Wever   check(SV("39.223300"), SV("{:%S}"), std::chrono::duration<int, std::ratio<101, 103>>{40});
112328584755SMark de Wever   check(SV("01.4755859375"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1511});
112428584755SMark de Wever 
112528584755SMark de Wever   // Test with all possible number of decimals [0, 18]. When it does not
112628584755SMark de Wever   // fit in 18 decimals it uses 6.
112728584755SMark de Wever   check(SV("05"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 1>>{5}); // 0
112828584755SMark de Wever 
112928584755SMark de Wever   check(SV("05.0"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 2>>{10}); // 1
113028584755SMark de Wever   check(SV("05.5"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2>>{11});   // 1
113128584755SMark de Wever 
113228584755SMark de Wever   check(SV("01.00"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4>>{4});         // 2
113328584755SMark de Wever   check(SV("01.50"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 4>>{6});      // 2
113428584755SMark de Wever   check(SV("01.75"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 4>>{7}); // 2
113528584755SMark de Wever 
113628584755SMark de Wever   check(SV("01.000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8>>{8});                          // 3
113728584755SMark de Wever   check(SV("01.0000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16>>{16});                       // 4
113828584755SMark de Wever   check(SV("01.00000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32>>{32});                      // 5
113928584755SMark de Wever   check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 64>>{64});                     // 6
114028584755SMark de Wever   check(SV("01.0000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 128>>{128});                  // 7
114128584755SMark de Wever   check(SV("01.00000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 256>>{256});                 // 8
114228584755SMark de Wever   check(SV("01.000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 512>>{512});                // 9
114328584755SMark de Wever   check(SV("01.0000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 1024>>{1024});             // 10
114428584755SMark de Wever   check(SV("01.00000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 2048>>{2048});            // 11
114528584755SMark de Wever   check(SV("01.000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 4096>>{4096});           // 12
114628584755SMark de Wever   check(SV("01.0000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 8192>>{8192});          // 13
114728584755SMark de Wever   check(SV("01.00000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 16384>>{16384});       // 14
114828584755SMark de Wever   check(SV("01.000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 32768>>{32768});      // 15
114928584755SMark de Wever   check(SV("01.0000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 65536>>{65536});     // 16
115028584755SMark de Wever   check(SV("01.00000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 131072>>{131072});  // 17
115128584755SMark de Wever   check(SV("01.000000000000000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 262144>>{262144}); // 18
115228584755SMark de Wever   check(SV("01.000000"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 524288>>{524288});             // 19 -> 6
115328584755SMark de Wever 
115428584755SMark de Wever   // Infinite number of decimals will use 6 decimals.
115528584755SMark de Wever   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<int, std::ratio<1, 9>>{1});
115628584755SMark de Wever   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<float, std::ratio<1, 9>>{1});
115728584755SMark de Wever   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<double, std::ratio<1, 9>>{1});
115828584755SMark de Wever   check(SV("00.111111"), SV("{:%S}"), std::chrono::duration<long double, std::ratio<1, 9>>{1});
115928584755SMark de Wever }
116028584755SMark de Wever 
116128584755SMark de Wever template <class CharT>
11626c97ad4eSMark de Wever static void test_unsigned_duration() {
11636c97ad4eSMark de Wever   // Reported in https://github.com/llvm/llvm-project/issues/96820
11646c97ad4eSMark de Wever   using namespace std::literals::chrono_literals;
11656c97ad4eSMark de Wever 
11666c97ad4eSMark de Wever   check(SV("1as"), SV("{}"), std::chrono::duration<unsigned short, std::atto>(1));
11676c97ad4eSMark de Wever   check(SV("1fs"), SV("{}"), std::chrono::duration<unsigned, std::femto>(1));
11686c97ad4eSMark de Wever   check(SV("1ps"), SV("{}"), std::chrono::duration<unsigned long, std::pico>(1));
11696c97ad4eSMark de Wever   check(SV("1ns"), SV("{}"), std::chrono::duration<unsigned long long, std::nano>(1));
11706c97ad4eSMark de Wever }
11716c97ad4eSMark de Wever 
11726c97ad4eSMark de Wever template <class CharT>
1173719c3dc6SMark de Wever static void test() {
1174719c3dc6SMark de Wever   using namespace std::literals::chrono_literals;
1175719c3dc6SMark de Wever 
1176719c3dc6SMark de Wever   test_no_chrono_specs<CharT>();
1177719c3dc6SMark de Wever   test_valid_values<CharT>();
11786c97ad4eSMark de Wever   test_unsigned_duration<CharT>();
117928584755SMark de Wever   test_pr62082<CharT>();
118028584755SMark de Wever 
1181719c3dc6SMark de Wever   check_invalid_types<CharT>(
1182719c3dc6SMark de Wever       {SV("H"), SV("I"), SV("j"), SV("M"), SV("n"), SV("O"),  SV("p"),  SV("q"),  SV("Q"),  SV("r"),
1183719c3dc6SMark de Wever        SV("R"), SV("S"), SV("t"), SV("T"), SV("X"), SV("EX"), SV("OH"), SV("OI"), SV("OM"), SV("OS")},
1184719c3dc6SMark de Wever       0ms);
1185719c3dc6SMark de Wever 
1186402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), 0ms);
1187402eb2efSMark de Wever   check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), 0ms);
1188402eb2efSMark de Wever   check_exception("End of input while parsing a conversion specifier", SV("{:%"), 0ms);
1189719c3dc6SMark de Wever   check_exception("End of input while parsing the modifier E", SV("{:%E"), 0ms);
1190719c3dc6SMark de Wever   check_exception("End of input while parsing the modifier O", SV("{:%O"), 0ms);
1191719c3dc6SMark de Wever 
1192b397921fSLouis Dionne   // Make sure the required values work, based on their minimum number of required bits per [time.syn].
1193a4814bdcSMark de Wever   check(SV("23:47:16.854775807"),
1194a4814bdcSMark de Wever         SV("{:%T}"),
1195a4814bdcSMark de Wever         std::chrono::nanoseconds{0x7fff'ffff'ffff'ffffll}); // 64 bit signed value max
1196a4814bdcSMark de Wever   check(SV("23:35:09.481983"),
1197a4814bdcSMark de Wever         SV("{:%T}"),
1198a4814bdcSMark de Wever         std::chrono::microseconds{0x003f'ffff'ffff'ffffll});                                 // 55 bit signed value max
1199a4814bdcSMark de Wever   check(SV("06:20:44.415"), SV("{:%T}"), std::chrono::milliseconds{0x0000'fff'ffff'ffffll}); // 45 bit signed value max
1200a4814bdcSMark de Wever   check(SV("01:53:03"), SV("{:%T}"), std::chrono::seconds{0x0000'0003'ffff'ffffll});         // 35 bit signed value max
1201a4814bdcSMark de Wever   check(SV("12:15:00"), SV("{:%T}"), std::chrono::minutes{0x0fff'ffff});                     // 29 bit signed value max
1202a4814bdcSMark de Wever   check(SV("15:00:00"), SV("{:%T}"), std::chrono::hours{0x003f'ffff});                       // 23 bit signed value max
1203a4814bdcSMark de Wever   check(SV("00:00:00"), SV("{:%T}"), std::chrono::days{0x0ff'ffff});                         // 25 bit signed value max
1204a4814bdcSMark de Wever   check(SV("00:00:00"), SV("{:%T}"), std::chrono::weeks{0x003f'ffff});                       // 22 bit signed value max
1205a4814bdcSMark de Wever   check(SV("21:11:42"), SV("{:%T}"), std::chrono::months{0x0007'ffff});                      // 20 bit signed value max
1206a4814bdcSMark de Wever   check(SV("05:42:00"), SV("{:%T}"), std::chrono::years{0xffff});                            // 17 bit signed value max
1207a4814bdcSMark de Wever 
1208719c3dc6SMark de Wever   // Precision not allowed
1209402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), 0ms);
1210719c3dc6SMark de Wever }
1211719c3dc6SMark de Wever 
1212719c3dc6SMark de Wever int main(int, char**) {
1213719c3dc6SMark de Wever   test<char>();
1214719c3dc6SMark de Wever 
1215719c3dc6SMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
1216719c3dc6SMark de Wever   test<wchar_t>();
1217719c3dc6SMark de Wever #endif
1218719c3dc6SMark de Wever 
1219719c3dc6SMark de Wever   return 0;
1220719c3dc6SMark de Wever }
1221