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