xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.year_month_weekday_last.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::year_month_weekday_last, 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 
38 template <class CharT>
39 static void test_no_chrono_specs() {
40   // Valid
41   check(SV("1970/Jan/Mon[last]"),
42         SV("{}"),
43         std::chrono::year_month_weekday_last{
44             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
45   check(SV("*1970/Jan/Mon[last]*"),
46         SV("{:*^20}"),
47         std::chrono::year_month_weekday_last{
48             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
49   check(SV("*1970/Jan/Mon[last]"),
50         SV("{:*>19}"),
51         std::chrono::year_month_weekday_last{
52             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
53 
54   // Invalid
55   check(SV("1970/Jan/8 is not a valid weekday[last]"),
56         SV("{}"),
57         std::chrono::year_month_weekday_last{
58             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
59   check(SV("1970/0 is not a valid month/Mon[last]"),
60         SV("{}"),
61         std::chrono::year_month_weekday_last{
62             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
63   check(SV("-32768 is not a valid year/Jan/Mon[last]"),
64         SV("{}"),
65         std::chrono::year_month_weekday_last{
66             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
67 }
68 
69 template <class CharT>
70 static void test_invalid_values() {
71   // *** Invalid weekday ***
72 
73   // Weekday name conversion
74   check_exception(
75       "Formatting a weekday name needs a valid weekday",
76       SV("{:%a}"),
77       std::chrono::year_month_weekday_last{
78           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
79   check_exception(
80       "Formatting a weekday name needs a valid weekday",
81       SV("{:%A}"),
82       std::chrono::year_month_weekday_last{
83           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
84 
85   // Weekday conversion
86   check_exception(
87       "Formatting a weekday needs a valid weekday",
88       SV("{:%u}"),
89       std::chrono::year_month_weekday_last{
90           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
91   check_exception(
92       "Formatting a weekday needs a valid weekday",
93       SV("{:%w}"),
94       std::chrono::year_month_weekday_last{
95           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
96   check_exception(
97       "Formatting a weekday needs a valid weekday",
98       SV("{:%Ou}"),
99       std::chrono::year_month_weekday_last{
100           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
101   check_exception(
102       "Formatting a weekday needs a valid weekday",
103       SV("{:%Ow}"),
104       std::chrono::year_month_weekday_last{
105           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
106 
107   // Day of year field
108   check_exception(
109       "Formatting a day of year needs a valid date",
110       SV("{:%j}"),
111       std::chrono::year_month_weekday_last{
112           std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
113 
114   // Month name conversion
115   check(SV("Jan"),
116         SV("{:%b}"),
117         std::chrono::year_month_weekday_last{
118             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
119   check(SV("Jan"),
120         SV("{:%h}"),
121         std::chrono::year_month_weekday_last{
122             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
123   check(SV("January"),
124         SV("{:%B}"),
125         std::chrono::year_month_weekday_last{
126             std::chrono::year{1970}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{8}}});
127 
128   // *** Invalid month ***
129 
130   // Weekday name conversion
131   check(SV("Mon"),
132         SV("{:%a}"),
133         std::chrono::year_month_weekday_last{
134             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
135   check(SV("Monday"),
136         SV("{:%A}"),
137         std::chrono::year_month_weekday_last{
138             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
139   // Weekday conversion
140   check(SV("1"),
141         SV("{:%u}"),
142         std::chrono::year_month_weekday_last{
143             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
144   check(SV("1"),
145         SV("{:%w}"),
146         std::chrono::year_month_weekday_last{
147             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
148   check(SV("1"),
149         SV("{:%Ou}"),
150         std::chrono::year_month_weekday_last{
151             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
152   check(SV("1"),
153         SV("{:%Ow}"),
154         std::chrono::year_month_weekday_last{
155             std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
156 
157   // Day of year field
158   check_exception(
159       "Formatting a day of year needs a valid date",
160       SV("{:%j}"),
161       std::chrono::year_month_weekday_last{
162           std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
163 
164   // Month name conversion
165   check_exception(
166       "Formatting a month name from an invalid month number",
167       SV("{:%b}"),
168       std::chrono::year_month_weekday_last{
169           std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
170   check_exception(
171       "Formatting a month name from an invalid month number",
172       SV("{:%h}"),
173       std::chrono::year_month_weekday_last{
174           std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
175   check_exception(
176       "Formatting a month name from an invalid month number",
177       SV("{:%B}"),
178       std::chrono::year_month_weekday_last{
179           std::chrono::year{1970}, std::chrono::month{0}, std::chrono::weekday_last{std::chrono::weekday{1}}});
180 
181   // *** Invalid year ***
182 
183   // Weekday name conversion
184   check(SV("Mon"),
185         SV("{:%a}"),
186         std::chrono::year_month_weekday_last{
187             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
188   check(SV("Monday"),
189         SV("{:%A}"),
190         std::chrono::year_month_weekday_last{
191             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
192 
193   // Weekday conversion
194   check(SV("1"),
195         SV("{:%u}"),
196         std::chrono::year_month_weekday_last{
197             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
198   check(SV("1"),
199         SV("{:%w}"),
200         std::chrono::year_month_weekday_last{
201             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
202   check(SV("1"),
203         SV("{:%Ou}"),
204         std::chrono::year_month_weekday_last{
205             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
206   check(SV("1"),
207         SV("{:%Ow}"),
208         std::chrono::year_month_weekday_last{
209             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
210 
211   // Day of year field
212   check_exception(
213       "Formatting a day of year needs a valid date",
214       SV("{:%j}"),
215       std::chrono::year_month_weekday_last{
216           std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
217 
218   // Month name conversion
219   check(SV("Jan"),
220         SV("{:%b}"),
221         std::chrono::year_month_weekday_last{
222             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
223   check(SV("Jan"),
224         SV("{:%h}"),
225         std::chrono::year_month_weekday_last{
226             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
227   check(SV("January"),
228         SV("{:%B}"),
229         std::chrono::year_month_weekday_last{
230             std::chrono::year{-32768}, std::chrono::month{1}, std::chrono::weekday_last{std::chrono::weekday{1}}});
231 }
232 
233 template <class CharT>
234 static void test() {
235   test_no_chrono_specs<CharT>();
236   test_invalid_values<CharT>();
237 }
238 
239 int main(int, char**) {
240   test<char>();
241 
242 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
243   test<wchar_t>();
244 #endif
245 
246   return 0;
247 }
248