xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.year_month.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1105fef5dSMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
3105fef5dSMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4105fef5dSMark de Wever // See https://llvm.org/LICENSE.txt for license information.
5105fef5dSMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6105fef5dSMark de Wever //
7105fef5dSMark de Wever //===----------------------------------------------------------------------===//
8105fef5dSMark de Wever 
9105fef5dSMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17
10105fef5dSMark de Wever // UNSUPPORTED: no-localization
11520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
12105fef5dSMark de Wever 
133d334df5SLouis Dionne // TODO FMT This test should not require std::to_chars(floating-point)
14f0fc8c48SLouis Dionne // XFAIL: availability-fp_to_chars-missing
153d334df5SLouis Dionne 
16105fef5dSMark de Wever // REQUIRES: locale.fr_FR.UTF-8
17105fef5dSMark de Wever // REQUIRES: locale.ja_JP.UTF-8
18105fef5dSMark de Wever 
19105fef5dSMark de Wever // <chrono>
20105fef5dSMark de Wever 
21105fef5dSMark de Wever // template<class charT> struct formatter<chrono::year_month, charT>;
22105fef5dSMark de Wever 
23105fef5dSMark de Wever #include <chrono>
24105fef5dSMark de Wever #include <format>
25105fef5dSMark de Wever 
26105fef5dSMark de Wever #include <cassert>
27105fef5dSMark de Wever #include <concepts>
28105fef5dSMark de Wever #include <locale>
29105fef5dSMark de Wever #include <iostream>
30105fef5dSMark de Wever #include <type_traits>
31105fef5dSMark de Wever 
32105fef5dSMark de Wever #include "formatter_tests.h"
33105fef5dSMark de Wever #include "make_string.h"
34105fef5dSMark de Wever #include "platform_support.h" // locale name macros
35105fef5dSMark de Wever #include "string_literal.h"
36105fef5dSMark de Wever #include "test_macros.h"
37105fef5dSMark de Wever 
38105fef5dSMark de Wever template <class CharT>
39105fef5dSMark de Wever static void test_no_chrono_specs() {
40105fef5dSMark de Wever   // Valid month
41105fef5dSMark de Wever   check(SV("1970/Jan"), SV("{}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
42105fef5dSMark de Wever   check(SV("*1970/Jan*"), SV("{:*^10}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
43105fef5dSMark de Wever   check(SV("*1970/Jan"), SV("{:*>9}"), std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{1}});
44105fef5dSMark de Wever 
45105fef5dSMark de Wever   // Invalid month_day
46105fef5dSMark de Wever   check(SV("1970/0 is not a valid month"),
47105fef5dSMark de Wever         SV("{}"),
48105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
49105fef5dSMark de Wever   check(SV("*1970/0 is not a valid month*"),
50105fef5dSMark de Wever         SV("{:*^29}"),
51105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
52105fef5dSMark de Wever }
53105fef5dSMark de Wever 
54105fef5dSMark de Wever template <class CharT>
55105fef5dSMark de Wever static void test_invalid_values() {
56105fef5dSMark de Wever   // Test that %b and %B throw an exception.
57402eb2efSMark de Wever   check_exception("Formatting a month name from an invalid month number",
58105fef5dSMark de Wever                   SV("{:%b}"),
59105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
60105fef5dSMark de Wever 
61402eb2efSMark de Wever   check_exception("Formatting a month name from an invalid month number",
62105fef5dSMark de Wever                   SV("{:%B}"),
63105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::month{0}});
64105fef5dSMark de Wever }
65105fef5dSMark de Wever 
66105fef5dSMark de Wever template <class CharT>
67105fef5dSMark de Wever static void test_valid_values() {
68105fef5dSMark de Wever   constexpr std::basic_string_view<CharT> fmt = SV(
69105fef5dSMark de Wever       "{:"
70105fef5dSMark de Wever       "%%b='%b'%t"
71105fef5dSMark de Wever       "%%B='%B'%t"
72105fef5dSMark de Wever       "%%C='%C'%t"
73105fef5dSMark de Wever       "%%h='%h'%t"
74105fef5dSMark de Wever       "%%y='%y'%t"
75105fef5dSMark de Wever       "%%Y='%Y'%t"
76105fef5dSMark de Wever       "%%EC='%EC'%t"
77105fef5dSMark de Wever       "%%Ey='%Ey'%t"
78105fef5dSMark de Wever       "%%EY='%EY'%t"
79105fef5dSMark de Wever       "%%Oy='%Oy'%t"
80105fef5dSMark de Wever       "%n}");
81105fef5dSMark de Wever 
82105fef5dSMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV(
83105fef5dSMark de Wever       "{:L"
84105fef5dSMark de Wever       "%%b='%b'%t"
85105fef5dSMark de Wever       "%%B='%B'%t"
86105fef5dSMark de Wever       "%%C='%C'%t"
87105fef5dSMark de Wever       "%%h='%h'%t"
88105fef5dSMark de Wever       "%%y='%y'%t"
89105fef5dSMark de Wever       "%%Y='%Y'%t"
90105fef5dSMark de Wever       "%%EC='%EC'%t"
91105fef5dSMark de Wever       "%%Ey='%Ey'%t"
92105fef5dSMark de Wever       "%%EY='%EY'%t"
93105fef5dSMark de Wever       "%%Oy='%Oy'%t"
94105fef5dSMark de Wever       "%n}");
95105fef5dSMark de Wever 
96105fef5dSMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
97105fef5dSMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
98105fef5dSMark de Wever 
99105fef5dSMark de Wever   // Non localized output using C-locale
100105fef5dSMark de Wever   check(SV("%b='Jan'\t"
101105fef5dSMark de Wever            "%B='January'\t"
102105fef5dSMark de Wever            "%C='19'\t"
103105fef5dSMark de Wever            "%h='Jan'\t"
104105fef5dSMark de Wever            "%y='70'\t"
105105fef5dSMark de Wever            "%Y='1970'\t"
106105fef5dSMark de Wever            "%EC='19'\t"
107105fef5dSMark de Wever            "%Ey='70'\t"
108105fef5dSMark de Wever            "%EY='1970'\t"
109105fef5dSMark de Wever            "%Oy='70'\t"
110105fef5dSMark de Wever            "\n"),
111105fef5dSMark de Wever         fmt,
112105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
113105fef5dSMark de Wever 
114105fef5dSMark de Wever   check(SV("%b='May'\t"
115105fef5dSMark de Wever            "%B='May'\t"
116105fef5dSMark de Wever            "%C='20'\t"
117105fef5dSMark de Wever            "%h='May'\t"
118105fef5dSMark de Wever            "%y='04'\t"
119105fef5dSMark de Wever            "%Y='2004'\t"
120105fef5dSMark de Wever            "%EC='20'\t"
121105fef5dSMark de Wever            "%Ey='04'\t"
122105fef5dSMark de Wever            "%EY='2004'\t"
123105fef5dSMark de Wever            "%Oy='04'\t"
124105fef5dSMark de Wever            "\n"),
125105fef5dSMark de Wever         fmt,
126105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
127105fef5dSMark de Wever 
128105fef5dSMark de Wever   // Use the global locale (fr_FR)
129105fef5dSMark de Wever   check(SV(
130105fef5dSMark de Wever #if defined(__APPLE__)
131105fef5dSMark de Wever             "%b='jan'\t"
132105fef5dSMark de Wever #else
133105fef5dSMark de Wever             "%b='janv.'\t"
134105fef5dSMark de Wever #endif
135105fef5dSMark de Wever             "%B='janvier'\t"
136105fef5dSMark de Wever             "%C='19'\t"
137105fef5dSMark de Wever #if defined(__APPLE__)
138105fef5dSMark de Wever             "%h='jan'\t"
139105fef5dSMark de Wever #else
140105fef5dSMark de Wever             "%h='janv.'\t"
141105fef5dSMark de Wever #endif
142105fef5dSMark de Wever             "%y='70'\t"
143105fef5dSMark de Wever             "%Y='1970'\t"
144105fef5dSMark de Wever             "%EC='19'\t"
145105fef5dSMark de Wever             "%Ey='70'\t"
146105fef5dSMark de Wever             "%EY='1970'\t"
147105fef5dSMark de Wever             "%Oy='70'\t"
148105fef5dSMark de Wever             "\n"),
149105fef5dSMark de Wever         lfmt,
150105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
151105fef5dSMark de Wever 
152105fef5dSMark de Wever   check(SV("%b='mai'\t"
153105fef5dSMark de Wever            "%B='mai'\t"
154105fef5dSMark de Wever            "%C='20'\t"
155105fef5dSMark de Wever            "%h='mai'\t"
156105fef5dSMark de Wever            "%y='04'\t"
157105fef5dSMark de Wever            "%Y='2004'\t"
158105fef5dSMark de Wever            "%EC='20'\t"
159105fef5dSMark de Wever            "%Ey='04'\t"
160105fef5dSMark de Wever            "%EY='2004'\t"
161105fef5dSMark de Wever            "%Oy='04'\t"
162105fef5dSMark de Wever            "\n"),
163105fef5dSMark de Wever         lfmt,
164105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
165105fef5dSMark de Wever 
166105fef5dSMark de Wever   // Use supplied locale (ja_JP)
167105fef5dSMark de Wever   check(loc,
168105fef5dSMark de Wever         SV(
169105fef5dSMark de Wever #if defined(_WIN32)
170105fef5dSMark de Wever             "%b='1'\t"
171105fef5dSMark de Wever #elif defined(_AIX)      // defined(_WIN32)
172105fef5dSMark de Wever             "%b='1月'\t"
173105fef5dSMark de Wever #elif defined(__APPLE__) // defined(_WIN32)
174105fef5dSMark de Wever             "%b=' 1'\t"
175105fef5dSMark de Wever #else                    // defined(_WIN32)
176105fef5dSMark de Wever             "%b=' 1月'\t"
177105fef5dSMark de Wever #endif                   // defined(_WIN32)
178105fef5dSMark de Wever             "%B='1月'\t"
179105fef5dSMark de Wever             "%C='19'\t"
180105fef5dSMark de Wever #if defined(_WIN32)
181105fef5dSMark de Wever             "%h='1'\t"
182105fef5dSMark de Wever #elif defined(_AIX)      // defined(_WIN32)
183105fef5dSMark de Wever             "%h='1月'\t"
184105fef5dSMark de Wever #elif defined(__APPLE__) // defined(_WIN32)
185105fef5dSMark de Wever             "%h=' 1'\t"
186105fef5dSMark de Wever #else                    // defined(_WIN32)
187105fef5dSMark de Wever             "%h=' 1月'\t"
188105fef5dSMark de Wever #endif                   // defined(_WIN32)
189105fef5dSMark de Wever             "%y='70'\t"
190105fef5dSMark de Wever             "%Y='1970'\t"
1918f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
192105fef5dSMark de Wever             "%EC='19'\t"
193105fef5dSMark de Wever             "%Ey='70'\t"
194105fef5dSMark de Wever             "%EY='1970'\t"
195105fef5dSMark de Wever             "%Oy='70'\t"
1968f01029bSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
197105fef5dSMark de Wever             "%EC='昭和'\t"
198105fef5dSMark de Wever             "%Ey='45'\t"
199105fef5dSMark de Wever             "%EY='昭和45年'\t"
200105fef5dSMark de Wever             "%Oy='七十'\t"
2018f01029bSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
202105fef5dSMark de Wever             "\n"),
203105fef5dSMark de Wever         lfmt,
204105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
205105fef5dSMark de Wever 
206105fef5dSMark de Wever   check(loc,
207105fef5dSMark de Wever         SV(
208105fef5dSMark de Wever 
209105fef5dSMark de Wever #if defined(_WIN32)
210105fef5dSMark de Wever             "%b='5'\t"
211105fef5dSMark de Wever #elif defined(_AIX)      // defined(_WIN32)
212105fef5dSMark de Wever             "%b='5月'\t"
213105fef5dSMark de Wever #elif defined(__APPLE__) // defined(_WIN32)
214105fef5dSMark de Wever             "%b=' 5'\t"
215105fef5dSMark de Wever #else                    // defined(_WIN32)
216105fef5dSMark de Wever             "%b=' 5月'\t"
217105fef5dSMark de Wever #endif                   // defined(_WIN32)
218105fef5dSMark de Wever             "%B='5月'\t"
219105fef5dSMark de Wever             "%C='20'\t"
220105fef5dSMark de Wever #if defined(_WIN32)
221105fef5dSMark de Wever             "%h='5'\t"
222105fef5dSMark de Wever #elif defined(_AIX)      // defined(_WIN32)
223105fef5dSMark de Wever             "%h='5月'\t"
224105fef5dSMark de Wever #elif defined(__APPLE__) // defined(_WIN32)
225105fef5dSMark de Wever             "%h=' 5'\t"
226105fef5dSMark de Wever #else                    // defined(_WIN32)
227105fef5dSMark de Wever             "%h=' 5月'\t"
228105fef5dSMark de Wever #endif                   // defined(_WIN32)
229105fef5dSMark de Wever             "%y='04'\t"
230105fef5dSMark de Wever             "%Y='2004'\t"
2318f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
232105fef5dSMark de Wever             "%EC='20'\t"
233105fef5dSMark de Wever             "%Ey='04'\t"
234105fef5dSMark de Wever             "%EY='2004'\t"
235105fef5dSMark de Wever             "%Oy='04'\t"
2368f01029bSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
237105fef5dSMark de Wever             "%EC='平成'\t"
238105fef5dSMark de Wever             "%Ey='16'\t"
239105fef5dSMark de Wever             "%EY='平成16年'\t"
240105fef5dSMark de Wever             "%Oy='四'\t"
2418f01029bSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
242105fef5dSMark de Wever             "\n"),
243105fef5dSMark de Wever         lfmt,
244105fef5dSMark de Wever         std::chrono::year_month{std::chrono::year{2004}, std::chrono::May});
245105fef5dSMark de Wever 
246105fef5dSMark de Wever   std::locale::global(std::locale::classic());
247105fef5dSMark de Wever }
248105fef5dSMark de Wever 
249105fef5dSMark de Wever template <class CharT>
250105fef5dSMark de Wever static void test() {
251105fef5dSMark de Wever   test_no_chrono_specs<CharT>();
252105fef5dSMark de Wever   test_invalid_values<CharT>();
253105fef5dSMark de Wever   test_valid_values<CharT>();
254105fef5dSMark de Wever 
255105fef5dSMark de Wever   check_invalid_types<CharT>(
256105fef5dSMark de Wever       {SV("b"), SV("B"), SV("C"), SV("EC"), SV("Ey"), SV("EY"), SV("h"), SV("m"), SV("Om"), SV("Oy"), SV("y"), SV("Y")},
257105fef5dSMark de Wever       std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
258105fef5dSMark de Wever 
259402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'",
260105fef5dSMark de Wever                   SV("{:A"),
261105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
262402eb2efSMark de Wever   check_exception("The chrono specifiers contain a '{'",
263105fef5dSMark de Wever                   SV("{:%%{"),
264105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
265402eb2efSMark de Wever   check_exception("End of input while parsing a conversion specifier",
266105fef5dSMark de Wever                   SV("{:%"),
267105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
268105fef5dSMark de Wever   check_exception("End of input while parsing the modifier E",
269105fef5dSMark de Wever                   SV("{:%E"),
270105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
271105fef5dSMark de Wever   check_exception("End of input while parsing the modifier O",
272105fef5dSMark de Wever                   SV("{:%O"),
273105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
274105fef5dSMark de Wever 
275105fef5dSMark de Wever   // Precision not allowed
276402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'",
277105fef5dSMark de Wever                   SV("{:.3}"),
278105fef5dSMark de Wever                   std::chrono::year_month{std::chrono::year{1970}, std::chrono::January});
279105fef5dSMark de Wever }
280105fef5dSMark de Wever 
281105fef5dSMark de Wever int main(int, char**) {
282105fef5dSMark de Wever   test<char>();
283105fef5dSMark de Wever 
284105fef5dSMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
285105fef5dSMark de Wever   test<wchar_t>();
286105fef5dSMark de Wever #endif
287105fef5dSMark de Wever 
288105fef5dSMark de Wever   return 0;
289105fef5dSMark de Wever }
290