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::year_month_weekday, 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 "string_literal.h"
36#include "test_macros.h"
37
38template <class CharT>
39static void test_no_chrono_specs() {
40 // Valid year, valid month, valid day, valid index
41 check(SV("1970/Jan/Mon[1]"),
42 SV("{}"),
43 std::chrono::year_month_weekday{
44 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
45 check(SV("*1970/Jan/Mon[1]"),
46 SV("{:*>16}"),
47 std::chrono::year_month_weekday{
48 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
49 check(SV("*1970/Jan/Mon[1]*"),
50 SV("{:*^17}"),
51 std::chrono::year_month_weekday{
52 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
53
54 // Valid year, valid month, valid day, invalid index
55 check(SV("1970/Jan/Mon[7 is not a valid index]"),
56 SV("{}"),
57 std::chrono::year_month_weekday{
58 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
59
60 // Valid year, valid month, invalid day, valid index
61 check(SV("1970/Jan/13 is not a valid weekday[1]"),
62 SV("{}"),
63 std::chrono::year_month_weekday{
64 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
65
66 // Valid year, valid month, invalid day, invalid index
67 check(SV("1970/Jan/13 is not a valid weekday[7 is not a valid index]"),
68 SV("{}"),
69 std::chrono::year_month_weekday{
70 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
71
72 // Valid year, invalid month, valid day, invalid index
73 check(SV("1970/0 is not a valid month/Mon[7 is not a valid index]"),
74 SV("{}"),
75 std::chrono::year_month_weekday{
76 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
77
78 // Valid year, invalid month, invalid day, valid index
79 check(SV("1970/0 is not a valid month/13 is not a valid weekday[1]"),
80 SV("{}"),
81 std::chrono::year_month_weekday{
82 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
83
84 // Valid year, invalid month, invalid day, invalid index
85 check(SV("1970/0 is not a valid month/13 is not a valid weekday[7 is not a valid index]"),
86 SV("{}"),
87 std::chrono::year_month_weekday{
88 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
89
90 // Invalid year, valid month, valid day, valid index
91 check(
92 SV("-32768 is not a valid year/Jan/Mon[1]"),
93 SV("{}"),
94 std::chrono::year_month_weekday{
95 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
96
97 // Invalid year, valid month, valid day, invalid index
98 check(
99 SV("-32768 is not a valid year/Jan/Mon[7 is not a valid index]"),
100 SV("{}"),
101 std::chrono::year_month_weekday{
102 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
103
104 // Invalid year, valid month, invalid day, valid index
105 check(
106 SV("-32768 is not a valid year/Jan/13 is not a valid weekday[1]"),
107 SV("{}"),
108 std::chrono::year_month_weekday{
109 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
110
111 // Invalid year, valid month, invalid day, invalid index
112 check(
113 SV("-32768 is not a valid year/Jan/13 is not a valid weekday[7 is not a valid index]"),
114 SV("{}"),
115 std::chrono::year_month_weekday{
116 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
117
118 // Invalid year, invalid month, valid day, invalid index
119 check(
120 SV("-32768 is not a valid year/0 is not a valid month/Mon[7 is not a valid index]"),
121 SV("{}"),
122 std::chrono::year_month_weekday{
123 std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
124
125 // Invalid year, invalid month, invalid day, valid index
126 check(
127 SV("-32768 is not a valid year/0 is not a valid month/13 is not a valid weekday[1]"),
128 SV("{}"),
129 std::chrono::year_month_weekday{
130 std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
131
132 // Invalid year, invalid month, invalid day, invalid index
133 check(
134 SV("-32768 is not a valid year/0 is not a valid month/13 is not a valid weekday[7 is not a valid index]"),
135 SV("{}"),
136 std::chrono::year_month_weekday{
137 std::chrono::year{-32768}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 7}});
138}
139
140// TODO FMT Should x throw?
141template <class CharT>
142static void test_invalid_values() {
143 // Test that %a, %A, %b, %B, %h, %j, %u, %U, %V, %w, %W, %Ou, %OU, %OV, %Ow, and %OW throw an exception.
144 check_exception(
145 "Formatting a weekday name needs a valid weekday",
146 SV("{:%a}"),
147 std::chrono::year_month_weekday{
148 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
149
150 check_exception(
151 "Formatting a weekday name needs a valid weekday",
152 SV("{:%A}"),
153 std::chrono::year_month_weekday{
154 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
155
156 check_exception(
157 "Formatting a month name from an invalid month number",
158 SV("{:%b}"),
159 std::chrono::year_month_weekday{
160 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
161
162 check_exception(
163 "Formatting a month name from an invalid month number",
164 SV("{:%B}"),
165 std::chrono::year_month_weekday{
166 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
167
168 check_exception(
169 "Formatting a month name from an invalid month number",
170 SV("{:%h}"),
171 std::chrono::year_month_weekday{
172 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
173
174 check_exception(
175 "Formatting a day of year needs a valid date",
176 SV("{:%j}"),
177 std::chrono::year_month_weekday{
178 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
179 check_exception(
180 "Formatting a day of year needs a valid date",
181 SV("{:%j}"),
182 std::chrono::year_month_weekday{
183 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
184 check_exception(
185 "Formatting a day of year needs a valid date",
186 SV("{:%j}"),
187 std::chrono::year_month_weekday{
188 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
189 check_exception(
190 "Formatting a day of year needs a valid date",
191 SV("{:%j}"),
192 std::chrono::year_month_weekday{
193 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
194
195 check_exception(
196 "Formatting a weekday needs a valid weekday",
197 SV("{:%u}"),
198 std::chrono::year_month_weekday{
199 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
200
201 check_exception(
202 "Formatting a week of year needs a valid date",
203 SV("{:%U}"),
204 std::chrono::year_month_weekday{
205 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
206 check_exception(
207 "Formatting a week of year needs a valid date",
208 SV("{:%U}"),
209 std::chrono::year_month_weekday{
210 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
211 check_exception(
212 "Formatting a week of year needs a valid date",
213 SV("{:%U}"),
214 std::chrono::year_month_weekday{
215 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
216 check_exception(
217 "Formatting a week of year needs a valid date",
218 SV("{:%U}"),
219 std::chrono::year_month_weekday{
220 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
221
222 check_exception(
223 "Formatting a week of year needs a valid date",
224 SV("{:%V}"),
225 std::chrono::year_month_weekday{
226 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
227 check_exception(
228 "Formatting a week of year needs a valid date",
229 SV("{:%V}"),
230 std::chrono::year_month_weekday{
231 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
232 check_exception(
233 "Formatting a week of year needs a valid date",
234 SV("{:%V}"),
235 std::chrono::year_month_weekday{
236 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
237 check_exception(
238 "Formatting a week of year needs a valid date",
239 SV("{:%V}"),
240 std::chrono::year_month_weekday{
241 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
242
243 check_exception(
244 "Formatting a weekday needs a valid weekday",
245 SV("{:%w}"),
246 std::chrono::year_month_weekday{
247 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
248
249 check_exception(
250 "Formatting a week of year needs a valid date",
251 SV("{:%W}"),
252 std::chrono::year_month_weekday{
253 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 7}});
254 check_exception(
255 "Formatting a week of year needs a valid date",
256 SV("{:%W}"),
257 std::chrono::year_month_weekday{
258 std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{13}, 1}});
259 check_exception(
260 "Formatting a week of year needs a valid date",
261 SV("{:%W}"),
262 std::chrono::year_month_weekday{
263 std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
264 check_exception(
265 "Formatting a week of year needs a valid date",
266 SV("{:%W}"),
267 std::chrono::year_month_weekday{
268 std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
269}
270
271template <class CharT>
272static void test_valid_md_values() {
273 constexpr std::basic_string_view<CharT> fmt =
274 SV("{:%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
275 constexpr std::basic_string_view<CharT> lfmt =
276 SV("{:L%%b='%b'%t%%B='%B'%t%%h='%h'%t%%m='%m'%t%%Om='%Om'%t%%d='%d'%t%%e='%e'%t%%Od='%Od'%t%%Oe='%Oe'%n}");
277
278 const std::locale loc(LOCALE_ja_JP_UTF_8);
279 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
280
281 // Non localized output using C-locale
282
283 check(SV("%b='Jan'\t%B='January'\t%h='Jan'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
284 fmt,
285 std::chrono::year_month_weekday{
286 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
287 check(SV("%b='Dec'\t%B='December'\t%h='Dec'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
288 fmt,
289 std::chrono::year_month_weekday{
290 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
291
292 // Use the global locale (fr_FR)
293#if defined(__APPLE__)
294 check(SV("%b='jan'\t%B='janvier'\t%h='jan'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
295 lfmt,
296 std::chrono::year_month_weekday{
297 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
298
299 check(SV("%b='déc'\t%B='décembre'\t%h='déc'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
300 lfmt,
301 std::chrono::year_month_weekday{
302 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
303
304#else // defined(__APPLE__)
305 check(SV("%b='janv.'\t%B='janvier'\t%h='janv.'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
306 lfmt,
307 std::chrono::year_month_weekday{
308 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
309 check(SV("%b='déc.'\t%B='décembre'\t%h='déc.'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
310 lfmt,
311 std::chrono::year_month_weekday{
312 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
313
314#endif // defined(__APPLE__)
315
316 // Use supplied locale (ja_JP)
317#if defined(_WIN32)
318 check(loc,
319 SV("%b='1'\t%B='1月'\t%h='1'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
320 lfmt,
321 std::chrono::year_month_weekday{
322 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
323
324 check(loc,
325 SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
326 lfmt,
327 std::chrono::year_month_weekday{
328 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
329
330#elif defined(_AIX) // defined(_WIN32)
331 check(loc,
332 SV("%b='1月'\t%B='1月'\t%h='1月'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
333 lfmt,
334 std::chrono::year_month_weekday{
335 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
336
337 check(loc,
338 SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
339 lfmt,
340 std::chrono::year_month_weekday{
341 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
342
343#elif defined(__APPLE__) // defined(_WIN32)
344 check(loc,
345 SV("%b=' 1'\t%B='1月'\t%h=' 1'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
346 lfmt,
347 std::chrono::year_month_weekday{
348 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
349
350 check(loc,
351 SV("%b='12'\t%B='12月'\t%h='12'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
352 lfmt,
353 std::chrono::year_month_weekday{
354 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
355
356#elif defined(__FreeBSD__) // defined(_WIN32)
357 check(loc,
358 SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='01'\t%d='01'\t%e=' 1'\t%Od='01'\t%Oe=' 1'\n"),
359 lfmt,
360 std::chrono::year_month_weekday{
361 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
362
363 check(loc,
364 SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='12'\t%d='20'\t%e='20'\t%Od='20'\t%Oe='20'\n"),
365 lfmt,
366 std::chrono::year_month_weekday{
367 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
368#else // defined(_WIN32)
369 check(loc,
370 SV("%b=' 1月'\t%B='1月'\t%h=' 1月'\t%m='01'\t%Om='一'\t%d='01'\t%e=' 1'\t%Od='一'\t%Oe='一'\n"),
371 lfmt,
372 std::chrono::year_month_weekday{
373 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
374
375 check(loc,
376 SV("%b='12月'\t%B='12月'\t%h='12月'\t%m='12'\t%Om='十二'\t%d='20'\t%e='20'\t%Od='二十'\t%Oe='二十'\n"),
377 lfmt,
378 std::chrono::year_month_weekday{
379 std::chrono::year{1970}, std::chrono::December, std::chrono::weekday_indexed{std::chrono::weekday{7}, 3}});
380
381#endif // defined(_WIN32)
382
383 std::locale::global(loc: std::locale::classic());
384}
385
386template <class CharT>
387static void test_valid_ymd_values() {
388 constexpr std::basic_string_view<CharT> fmt = SV(
389 "{:"
390 "%%C='%C'%t"
391 "%%D='%D'%t"
392 "%%F='%F'%t"
393 "%%j='%j'%t"
394 "%%g='%g'%t"
395 "%%G='%G'%t"
396 "%%u='%u'%t"
397 "%%U='%U'%t"
398 "%%V='%V'%t"
399 "%%w='%w'%t"
400 "%%W='%W'%t"
401 "%%x='%x'%t"
402 "%%y='%y'%t"
403 "%%Y='%Y'%t"
404 "%%Ex='%Ex'%t"
405 "%%EC='%EC'%t"
406 "%%Ey='%Ey'%t"
407 "%%EY='%EY'%t"
408 "%%Ou='%Ou'%t"
409 "%%OU='%OU'%t"
410 "%%OV='%OV'%t"
411 "%%Ow='%Ow'%t"
412 "%%OW='%OW'%t"
413 "%%Oy='%Oy'%t"
414 "%n}");
415
416 constexpr std::basic_string_view<CharT> lfmt = SV(
417 "{:L"
418 "%%C='%C'%t"
419 "%%D='%D'%t"
420 "%%F='%F'%t"
421 "%%j='%j'%t"
422 "%%g='%g'%t"
423 "%%G='%G'%t"
424 "%%u='%u'%t"
425 "%%U='%U'%t"
426 "%%V='%V'%t"
427 "%%w='%w'%t"
428 "%%W='%W'%t"
429 "%%x='%x'%t"
430 "%%y='%y'%t"
431 "%%Y='%Y'%t"
432 "%%Ex='%Ex'%t"
433 "%%EC='%EC'%t"
434 "%%Ey='%Ey'%t"
435 "%%EY='%EY'%t"
436 "%%Ou='%Ou'%t"
437 "%%OU='%OU'%t"
438 "%%OV='%OV'%t"
439 "%%Ow='%Ow'%t"
440 "%%OW='%OW'%t"
441 "%%Oy='%Oy'%t"
442 "%n}");
443
444 const std::locale loc(LOCALE_ja_JP_UTF_8);
445 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
446
447 // Non localized output using C-locale
448 check(
449 SV("%C='19'\t"
450 "%D='01/01/70'\t"
451 "%F='1970-01-01'\t"
452 "%j='001'\t"
453 "%g='70'\t"
454 "%G='1970'\t"
455 "%u='4'\t"
456 "%U='00'\t"
457 "%V='01'\t"
458 "%w='4'\t"
459 "%W='00'\t"
460 "%x='01/01/70'\t"
461 "%y='70'\t"
462 "%Y='1970'\t"
463 "%Ex='01/01/70'\t"
464 "%EC='19'\t"
465 "%Ey='70'\t"
466 "%EY='1970'\t"
467 "%Ou='4'\t"
468 "%OU='00'\t"
469 "%OV='01'\t"
470 "%Ow='4'\t"
471 "%OW='00'\t"
472 "%Oy='70'\t"
473 "\n"),
474 fmt,
475 std::chrono::year_month_weekday{
476 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
477
478 check(
479 SV("%C='20'\t"
480 "%D='05/29/04'\t"
481 "%F='2004-05-29'\t"
482 "%j='150'\t"
483 "%g='04'\t"
484 "%G='2004'\t"
485 "%u='6'\t"
486 "%U='21'\t"
487 "%V='22'\t"
488 "%w='6'\t"
489 "%W='21'\t"
490 "%x='05/29/04'\t"
491 "%y='04'\t"
492 "%Y='2004'\t"
493 "%Ex='05/29/04'\t"
494 "%EC='20'\t"
495 "%Ey='04'\t"
496 "%EY='2004'\t"
497 "%Ou='6'\t"
498 "%OU='21'\t"
499 "%OV='22'\t"
500 "%Ow='6'\t"
501 "%OW='21'\t"
502 "%Oy='04'\t"
503 "\n"),
504 fmt,
505 std::chrono::year_month_weekday{
506 std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
507
508 // Use the global locale (fr_FR)
509 check(
510 SV("%C='19'\t"
511 "%D='01/01/70'\t"
512 "%F='1970-01-01'\t"
513 "%j='001'\t"
514 "%g='70'\t"
515 "%G='1970'\t"
516 "%u='4'\t"
517 "%U='00'\t"
518 "%V='01'\t"
519 "%w='4'\t"
520 "%W='00'\t"
521#if defined(__APPLE__) || defined(__FreeBSD__)
522 "%x='01.01.1970'\t"
523#else
524 "%x='01/01/1970'\t"
525#endif
526 "%y='70'\t"
527 "%Y='1970'\t"
528#if defined(__APPLE__) || defined(__FreeBSD__)
529 "%Ex='01.01.1970'\t"
530#else
531 "%Ex='01/01/1970'\t"
532#endif
533 "%EC='19'\t"
534 "%Ey='70'\t"
535 "%EY='1970'\t"
536 "%Ou='4'\t"
537 "%OU='00'\t"
538 "%OV='01'\t"
539 "%Ow='4'\t"
540 "%OW='00'\t"
541 "%Oy='70'\t"
542 "\n"),
543 lfmt,
544 std::chrono::year_month_weekday{
545 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
546
547 check(
548 SV("%C='20'\t"
549 "%D='05/29/04'\t"
550 "%F='2004-05-29'\t"
551 "%j='150'\t"
552 "%g='04'\t"
553 "%G='2004'\t"
554 "%u='6'\t"
555 "%U='21'\t"
556 "%V='22'\t"
557 "%w='6'\t"
558 "%W='21'\t"
559#if defined(__APPLE__) || defined(__FreeBSD__)
560 "%x='29.05.2004'\t"
561#else
562 "%x='29/05/2004'\t"
563#endif
564 "%y='04'\t"
565 "%Y='2004'\t"
566#if defined(__APPLE__) || defined(__FreeBSD__)
567 "%Ex='29.05.2004'\t"
568#else
569 "%Ex='29/05/2004'\t"
570#endif
571 "%EC='20'\t"
572 "%Ey='04'\t"
573 "%EY='2004'\t"
574 "%Ou='6'\t"
575 "%OU='21'\t"
576 "%OV='22'\t"
577 "%Ow='6'\t"
578 "%OW='21'\t"
579 "%Oy='04'\t"
580 "\n"),
581 lfmt,
582 std::chrono::year_month_weekday{
583 std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
584
585 // Use supplied locale (ja_JP)
586 check(
587 loc,
588 SV("%C='19'\t"
589 "%D='01/01/70'\t"
590 "%F='1970-01-01'\t"
591 "%j='001'\t"
592 "%g='70'\t"
593 "%G='1970'\t"
594 "%u='4'\t"
595 "%U='00'\t"
596 "%V='01'\t"
597 "%w='4'\t"
598 "%W='00'\t"
599#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
600 "%x='1970/01/01'\t"
601#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
602 "%x='1970年01月01日'\t"
603#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
604 "%y='70'\t"
605 "%Y='1970'\t"
606#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
607 "%Ex='1970/01/01'\t"
608 "%EC='19'\t"
609 "%Ey='70'\t"
610 "%EY='1970'\t"
611 "%Ou='4'\t"
612 "%OU='00'\t"
613 "%OV='01'\t"
614 "%Ow='4'\t"
615 "%OW='00'\t"
616 "%Oy='70'\t"
617#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
618 "%Ex='昭和45年01月01日'\t"
619 "%EC='昭和'\t"
620 "%Ey='45'\t"
621 "%EY='昭和45年'\t"
622 "%Ou='四'\t"
623 "%OU='〇'\t"
624 "%OV='一'\t"
625 "%Ow='四'\t"
626 "%OW='〇'\t"
627 "%Oy='七十'\t"
628#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
629 "\n"),
630 lfmt,
631 std::chrono::year_month_weekday{
632 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{4}, 1}});
633
634 check(
635 loc,
636 SV("%C='20'\t"
637 "%D='05/29/04'\t"
638 "%F='2004-05-29'\t"
639 "%j='150'\t"
640 "%g='04'\t"
641 "%G='2004'\t"
642 "%u='6'\t"
643 "%U='21'\t"
644 "%V='22'\t"
645 "%w='6'\t"
646 "%W='21'\t"
647#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
648 "%x='2004/05/29'\t"
649#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
650 "%x='2004年05月29日'\t"
651#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
652 "%y='04'\t"
653 "%Y='2004'\t"
654#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
655 "%Ex='2004/05/29'\t"
656 "%EC='20'\t"
657 "%Ey='04'\t"
658 "%EY='2004'\t"
659 "%Ou='6'\t"
660 "%OU='21'\t"
661 "%OV='22'\t"
662 "%Ow='6'\t"
663 "%OW='21'\t"
664 "%Oy='04'\t"
665#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
666 "%Ex='平成16年05月29日'\t"
667 "%EC='平成'\t"
668 "%Ey='16'\t"
669 "%EY='平成16年'\t"
670 "%Ou='六'\t"
671 "%OU='二十一'\t"
672 "%OV='二十二'\t"
673 "%Ow='六'\t"
674 "%OW='二十一'\t"
675 "%Oy='四'\t"
676#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
677 "\n"),
678 lfmt,
679 std::chrono::year_month_weekday{
680 std::chrono::year{2004}, std::chrono::May, std::chrono::weekday_indexed{std::chrono::weekday{6}, 5}});
681
682 std::locale::global(loc: std::locale::classic());
683}
684
685template <class CharT>
686static void test_valid_values() {
687 // Fields only using month and day.
688 test_valid_md_values<CharT>();
689 // Fields only using year, month, and day.
690 test_valid_ymd_values<CharT>();
691}
692
693template <class CharT>
694static void test() {
695 test_no_chrono_specs<CharT>();
696 test_invalid_values<CharT>();
697 test_valid_values<CharT>();
698 check_invalid_types<CharT>(
699 {SV("a"), SV("A"), SV("b"), SV("B"), SV("C"), SV("d"), SV("D"), SV("e"), SV("EC"),
700 SV("Ex"), SV("Ey"), SV("EY"), SV("F"), SV("g"), SV("G"), SV("h"), SV("j"), SV("m"),
701 SV("Od"), SV("Oe"), SV("Om"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"),
702 SV("u"), SV("U"), SV("V"), SV("w"), SV("W"), SV("x"), SV("y"), SV("Y")},
703 std::chrono::year_month_weekday{
704 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
705
706 check_exception(
707 "The format specifier expects a '%' or a '}'",
708 SV("{:A"),
709 std::chrono::year_month_weekday{
710 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
711 check_exception(
712 "The chrono specifiers contain a '{'",
713 SV("{:%%{"),
714 std::chrono::year_month_weekday{
715 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
716 check_exception(
717 "End of input while parsing a conversion specifier",
718 SV("{:%"),
719 std::chrono::year_month_weekday{
720 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
721 check_exception(
722 "End of input while parsing the modifier E",
723 SV("{:%E"),
724 std::chrono::year_month_weekday{
725 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
726 check_exception(
727 "End of input while parsing the modifier O",
728 SV("{:%O"),
729 std::chrono::year_month_weekday{
730 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
731
732 // Precision not allowed
733 check_exception(
734 "The format specifier expects a '%' or a '}'",
735 SV("{:.3}"),
736 std::chrono::year_month_weekday{
737 std::chrono::year{1970}, std::chrono::January, std::chrono::weekday_indexed{std::chrono::weekday{1}, 1}});
738}
739
740int main(int, char**) {
741 test<char>();
742
743#ifndef TEST_HAS_NO_WIDE_CHARACTERS
744 test<wchar_t>();
745#endif
746
747 return 0;
748}
749

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