xref: /llvm-project/libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
12c1d7959SMark de Wever //===----------------------------------------------------------------------===//
2*6a54dfbfSLouis Dionne //
32c1d7959SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42c1d7959SMark de Wever // See https://llvm.org/LICENSE.txt for license information.
52c1d7959SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62c1d7959SMark de Wever //
72c1d7959SMark de Wever //===----------------------------------------------------------------------===//
82c1d7959SMark de Wever 
92c1d7959SMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17
102c1d7959SMark de Wever // UNSUPPORTED: no-localization
11520c7fbbSLouis Dionne // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
122c1d7959SMark de Wever 
132c1d7959SMark de Wever // TODO FMT This test should not require std::to_chars(floating-point)
142c1d7959SMark de Wever // XFAIL: availability-fp_to_chars-missing
152c1d7959SMark de Wever 
162c1d7959SMark de Wever // REQUIRES: locale.fr_FR.UTF-8
172c1d7959SMark de Wever // REQUIRES: locale.ja_JP.UTF-8
182c1d7959SMark de Wever 
192c1d7959SMark de Wever // <chrono>
202c1d7959SMark de Wever //
212c1d7959SMark de Wever // template<class charT> struct formatter<chrono::day, charT>;
222c1d7959SMark de Wever 
232c1d7959SMark de Wever #include <chrono>
242c1d7959SMark de Wever #include <format>
252c1d7959SMark de Wever 
262c1d7959SMark de Wever #include <cassert>
272c1d7959SMark de Wever #include <concepts>
282c1d7959SMark de Wever #include <locale>
292c1d7959SMark de Wever #include <iostream>
302c1d7959SMark de Wever #include <type_traits>
312c1d7959SMark de Wever 
322c1d7959SMark de Wever #include "formatter_tests.h"
332c1d7959SMark de Wever #include "make_string.h"
342c1d7959SMark de Wever #include "platform_support.h" // locale name macros
352c1d7959SMark de Wever #include "test_macros.h"
362c1d7959SMark de Wever 
372c1d7959SMark de Wever template <class CharT>
382c1d7959SMark de Wever static void test_no_chrono_specs() {
392c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
402c1d7959SMark de Wever 
412c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
422c1d7959SMark de Wever 
432c1d7959SMark de Wever   // Non localized output
44b9f3d241SMark de Wever 
45b9f3d241SMark de Wever   // [time.syn]
46b9f3d241SMark de Wever   //   using nanoseconds  = duration<signed integer type of at least 64 bits, nano>;
47b9f3d241SMark de Wever   //   using microseconds = duration<signed integer type of at least 55 bits, micro>;
48b9f3d241SMark de Wever   //   using milliseconds = duration<signed integer type of at least 45 bits, milli>;
49b9f3d241SMark de Wever   //   using seconds      = duration<signed integer type of at least 35 bits>;
50b9f3d241SMark de Wever   //   using minutes      = duration<signed integer type of at least 29 bits, ratio<  60>>;
51b9f3d241SMark de Wever   //   using hours        = duration<signed integer type of at least 23 bits, ratio<3600>>;
52b9f3d241SMark de Wever   check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::sys_seconds(-17'179'869'184s)); // Minimum value for 35 bits.
53b9f3d241SMark de Wever   check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::sys_seconds(-2'147'483'648s));
54b9f3d241SMark de Wever 
55b9f3d241SMark de Wever   check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::sys_seconds(-24h));
56b9f3d241SMark de Wever   check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::sys_seconds(-18h));
57b9f3d241SMark de Wever   check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::sys_seconds(-12h));
58b9f3d241SMark de Wever   check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::sys_seconds(-6h));
59b9f3d241SMark de Wever   check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::sys_seconds(-1s));
60b9f3d241SMark de Wever 
612c1d7959SMark de Wever   check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(0s));
622c1d7959SMark de Wever   check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(946'684'800s));
632c1d7959SMark de Wever   check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::sys_seconds(946'688'523s));
642c1d7959SMark de Wever 
65b9f3d241SMark de Wever   check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::sys_seconds(2'147'483'647s));
66b9f3d241SMark de Wever   check(SV("2514-05-30 01:53:03"), SV("{}"), std::chrono::sys_seconds(17'179'869'183s)); // Maximum value for 35 bits.
67b9f3d241SMark de Wever 
682c1d7959SMark de Wever   check(SV("2000-01-01 01:02:03.123"), SV("{}"), std::chrono::sys_time<std::chrono::milliseconds>(946'688'523'123ms));
692c1d7959SMark de Wever 
702c1d7959SMark de Wever   std::locale::global(std::locale::classic());
712c1d7959SMark de Wever }
722c1d7959SMark de Wever 
732c1d7959SMark de Wever template <class CharT>
742c1d7959SMark de Wever static void test_valid_values_year() {
752c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
762c1d7959SMark de Wever 
772c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt =
782c1d7959SMark de Wever       SV("{:%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");
792c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt =
802c1d7959SMark de Wever       SV("{:L%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");
812c1d7959SMark de Wever 
822c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
832c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
842c1d7959SMark de Wever 
852c1d7959SMark de Wever   // Non localized output using C-locale
862c1d7959SMark de Wever   check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
872c1d7959SMark de Wever         fmt,
882c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
892c1d7959SMark de Wever 
902c1d7959SMark de Wever   check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
912c1d7959SMark de Wever         fmt,
922c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
932c1d7959SMark de Wever 
942c1d7959SMark de Wever   // Use the global locale (fr_FR)
952c1d7959SMark de Wever   check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
962c1d7959SMark de Wever         lfmt,
972c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
982c1d7959SMark de Wever 
992c1d7959SMark de Wever   check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
1002c1d7959SMark de Wever         lfmt,
1012c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
1022c1d7959SMark de Wever 
1032c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
1048f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
1052c1d7959SMark de Wever   check(loc,
1062c1d7959SMark de Wever         SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),
1072c1d7959SMark de Wever         lfmt,
1082c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1092c1d7959SMark de Wever 
1102c1d7959SMark de Wever   check(loc,
1112c1d7959SMark de Wever         SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),
1122c1d7959SMark de Wever         lfmt,
1132c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
1148f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)
1152c1d7959SMark de Wever   check(loc,
1162c1d7959SMark de Wever         SV("%C='19'\t%EC='昭和'\t%y='70'\t%Oy='七十'\t%Ey='45'\t%Y='1970'\t%EY='昭和45年'\n"),
1172c1d7959SMark de Wever         lfmt,
1182c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1192c1d7959SMark de Wever 
1202c1d7959SMark de Wever   check(loc,
1212c1d7959SMark de Wever         SV("%C='20'\t%EC='平成'\t%y='09'\t%Oy='九'\t%Ey='21'\t%Y='2009'\t%EY='平成21年'\n"),
1222c1d7959SMark de Wever         lfmt,
1232c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
1248f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)
1252c1d7959SMark de Wever 
1262c1d7959SMark de Wever   std::locale::global(std::locale::classic());
1272c1d7959SMark de Wever }
1282c1d7959SMark de Wever 
1292c1d7959SMark de Wever template <class CharT>
1302c1d7959SMark de Wever static void test_valid_values_month() {
1312c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
1322c1d7959SMark de Wever 
1332c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");
1342c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");
1352c1d7959SMark de Wever 
1362c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
1372c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
1382c1d7959SMark de Wever 
1392c1d7959SMark de Wever   // Non localized output using C-locale
1402c1d7959SMark de Wever   check(SV("%b='Jan'\t%h='Jan'\t%B='January'\t%m='01'\t%Om='01'\n"),
1412c1d7959SMark de Wever         fmt,
1422c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1432c1d7959SMark de Wever 
1442c1d7959SMark de Wever   check(SV("%b='May'\t%h='May'\t%B='May'\t%m='05'\t%Om='05'\n"),
1452c1d7959SMark de Wever         fmt,
1462c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
1472c1d7959SMark de Wever 
1482c1d7959SMark de Wever   // Use the global locale (fr_FR)
1492c1d7959SMark de Wever #if defined(__APPLE__)
1502c1d7959SMark de Wever   check(SV("%b='jan'\t%h='jan'\t%B='janvier'\t%m='01'\t%Om='01'\n"),
1512c1d7959SMark de Wever         lfmt,
1522c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1532c1d7959SMark de Wever #else
1542c1d7959SMark de Wever   check(SV("%b='janv.'\t%h='janv.'\t%B='janvier'\t%m='01'\t%Om='01'\n"),
1552c1d7959SMark de Wever         lfmt,
1562c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1572c1d7959SMark de Wever #endif
1582c1d7959SMark de Wever 
1592c1d7959SMark de Wever   check(SV("%b='mai'\t%h='mai'\t%B='mai'\t%m='05'\t%Om='05'\n"),
1602c1d7959SMark de Wever         lfmt,
1612c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
1622c1d7959SMark de Wever 
1632c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
1642c1d7959SMark de Wever #ifdef _WIN32
1652c1d7959SMark de Wever   check(loc,
1662c1d7959SMark de Wever         SV("%b='1'\t%h='1'\t%B='1月'\t%m='01'\t%Om='01'\n"),
1672c1d7959SMark de Wever         lfmt,
1682c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1692c1d7959SMark de Wever 
1702c1d7959SMark de Wever   check(loc,
1712c1d7959SMark de Wever         SV("%b='5'\t%h='5'\t%B='5月'\t%m='05'\t%Om='05'\n"),
1722c1d7959SMark de Wever         lfmt,
1732c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
1742c1d7959SMark de Wever #elif defined(_AIX)                                // _WIN32
1752c1d7959SMark de Wever   check(loc,
1762c1d7959SMark de Wever         SV("%b='1月'\t%h='1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),
1772c1d7959SMark de Wever         lfmt,
1782c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1792c1d7959SMark de Wever 
1802c1d7959SMark de Wever   check(loc,
1812c1d7959SMark de Wever         SV("%b='5月'\t%h='5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),
1822c1d7959SMark de Wever         lfmt,
1832c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
1842c1d7959SMark de Wever #elif defined(__APPLE__)                           // _WIN32
1852c1d7959SMark de Wever   check(loc,
1862c1d7959SMark de Wever         SV("%b=' 1'\t%h=' 1'\t%B='1月'\t%m='01'\t%Om='01'\n"),
1872c1d7959SMark de Wever         lfmt,
1882c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1892c1d7959SMark de Wever 
1902c1d7959SMark de Wever   check(loc,
1912c1d7959SMark de Wever         SV("%b=' 5'\t%h=' 5'\t%B='5月'\t%m='05'\t%Om='05'\n"),
1922c1d7959SMark de Wever         lfmt,
1932c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
1948f01029bSMark de Wever #elif defined(__FreeBSD__)                         // _WIN32
1958f01029bSMark de Wever   check(loc,
1968f01029bSMark de Wever         SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),
1978f01029bSMark de Wever         lfmt,
1988f01029bSMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
1998f01029bSMark de Wever 
2008f01029bSMark de Wever   check(loc,
2018f01029bSMark de Wever         SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),
2028f01029bSMark de Wever         lfmt,
2038f01029bSMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
2042c1d7959SMark de Wever #else                                              // _WIN32
2052c1d7959SMark de Wever   check(loc,
2062c1d7959SMark de Wever         SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='一'\n"),
2072c1d7959SMark de Wever         lfmt,
2082c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2092c1d7959SMark de Wever 
2102c1d7959SMark de Wever   check(loc,
2112c1d7959SMark de Wever         SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='五'\n"),
2122c1d7959SMark de Wever         lfmt,
2132c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
2142c1d7959SMark de Wever #endif                                             // _WIN32
2152c1d7959SMark de Wever 
2162c1d7959SMark de Wever   std::locale::global(std::locale::classic());
2172c1d7959SMark de Wever }
2182c1d7959SMark de Wever 
2192c1d7959SMark de Wever template <class CharT>
2202c1d7959SMark de Wever static void test_valid_values_day() {
2212c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
2222c1d7959SMark de Wever 
2232c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");
2242c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");
2252c1d7959SMark de Wever 
2262c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
2272c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
2282c1d7959SMark de Wever 
2292c1d7959SMark de Wever   // Non localized output using C-locale
2302c1d7959SMark de Wever   check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
2312c1d7959SMark de Wever         fmt,
2322c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2332c1d7959SMark de Wever 
2342c1d7959SMark de Wever   check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
2352c1d7959SMark de Wever         fmt,
2362c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
2372c1d7959SMark de Wever 
2382c1d7959SMark de Wever   // Use the global locale (fr_FR)
2392c1d7959SMark de Wever   check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
2402c1d7959SMark de Wever         lfmt,
2412c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2422c1d7959SMark de Wever 
2432c1d7959SMark de Wever   check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
2442c1d7959SMark de Wever         lfmt,
2452c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
2462c1d7959SMark de Wever 
2472c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
2488f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
2492c1d7959SMark de Wever   check(loc,
2502c1d7959SMark de Wever         SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),
2512c1d7959SMark de Wever         lfmt,
2522c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2532c1d7959SMark de Wever 
2542c1d7959SMark de Wever   check(loc,
2552c1d7959SMark de Wever         SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),
2562c1d7959SMark de Wever         lfmt,
2572c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
2588f01029bSMark de Wever #else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
2592c1d7959SMark de Wever   check(loc,
2602c1d7959SMark de Wever         SV("%d='01'\t%Od='一'\t%e=' 1'\t%Oe='一'\n"),
2612c1d7959SMark de Wever         lfmt,
2622c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2632c1d7959SMark de Wever 
2642c1d7959SMark de Wever   check(loc,
2652c1d7959SMark de Wever         SV("%d='13'\t%Od='十三'\t%e='13'\t%Oe='十三'\n"),
2662c1d7959SMark de Wever         lfmt,
2672c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
2682c1d7959SMark de Wever 
2698f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
2702c1d7959SMark de Wever 
2712c1d7959SMark de Wever   std::locale::global(std::locale::classic());
2722c1d7959SMark de Wever }
2732c1d7959SMark de Wever 
2742c1d7959SMark de Wever template <class CharT>
2752c1d7959SMark de Wever static void test_valid_values_weekday() {
2762c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
2772c1d7959SMark de Wever 
2782c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt =
2792c1d7959SMark de Wever       SV("{:%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
2802c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt =
2812c1d7959SMark de Wever       SV("{:L%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");
2822c1d7959SMark de Wever 
2832c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
2842c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
2852c1d7959SMark de Wever 
2862c1d7959SMark de Wever   // Non localized output using C-locale
2872c1d7959SMark de Wever   check(SV("%a='Thu'\t%A='Thursday'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
2882c1d7959SMark de Wever         fmt,
2892c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
2902c1d7959SMark de Wever 
2912c1d7959SMark de Wever   check(SV("%a='Sun'\t%A='Sunday'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
2922c1d7959SMark de Wever         fmt,
2932c1d7959SMark de Wever         std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
2942c1d7959SMark de Wever 
2952c1d7959SMark de Wever   // Use the global locale (fr_FR)
2962c1d7959SMark de Wever #if defined(__APPLE__)
2972c1d7959SMark de Wever   check(SV("%a='Jeu'\t%A='Jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
2982c1d7959SMark de Wever         lfmt,
2992c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3002c1d7959SMark de Wever 
3012c1d7959SMark de Wever   check(SV("%a='Dim'\t%A='Dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
3022c1d7959SMark de Wever         lfmt,
3032c1d7959SMark de Wever         std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
3042c1d7959SMark de Wever #else
3052c1d7959SMark de Wever   check(SV("%a='jeu.'\t%A='jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
3062c1d7959SMark de Wever         lfmt,
3072c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3082c1d7959SMark de Wever 
3092c1d7959SMark de Wever   check(SV("%a='dim.'\t%A='dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
3102c1d7959SMark de Wever         lfmt,
3112c1d7959SMark de Wever         std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
3122c1d7959SMark de Wever #endif
3132c1d7959SMark de Wever 
3142c1d7959SMark de Wever   // Use supplied locale (ja_JP).
3152c1d7959SMark de Wever   // This locale has a different alternate, but not on all platforms
3168f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
3172c1d7959SMark de Wever   check(loc,
3182c1d7959SMark de Wever         SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),
3192c1d7959SMark de Wever         lfmt,
3202c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3212c1d7959SMark de Wever 
3222c1d7959SMark de Wever   check(loc,
3232c1d7959SMark de Wever         SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),
3242c1d7959SMark de Wever         lfmt,
3252c1d7959SMark de Wever         std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
3268f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
3272c1d7959SMark de Wever   check(loc,
3282c1d7959SMark de Wever         SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\n"),
3292c1d7959SMark de Wever         lfmt,
3302c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3312c1d7959SMark de Wever 
3322c1d7959SMark de Wever   check(loc,
3332c1d7959SMark de Wever         SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\n"),
3342c1d7959SMark de Wever         lfmt,
3352c1d7959SMark de Wever         std::chrono::sys_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106
3368f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
3372c1d7959SMark de Wever 
3382c1d7959SMark de Wever   std::locale::global(std::locale::classic());
3392c1d7959SMark de Wever }
3402c1d7959SMark de Wever 
3412c1d7959SMark de Wever template <class CharT>
3422c1d7959SMark de Wever static void test_valid_values_day_of_year() {
3432c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
3442c1d7959SMark de Wever 
3452c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%j='%j'%n}");
3462c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%j='%j'%n}");
3472c1d7959SMark de Wever 
3482c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
3492c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
3502c1d7959SMark de Wever 
3512c1d7959SMark de Wever   // Non localized output using C-locale
3522c1d7959SMark de Wever   check(SV("%j='001'\n"), fmt, std::chrono::sys_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970
3532c1d7959SMark de Wever   check(SV("%j='138'\n"), fmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
3542c1d7959SMark de Wever 
3552c1d7959SMark de Wever   // Use the global locale (fr_FR)
3562c1d7959SMark de Wever   check(SV("%j='001'\n"), lfmt, std::chrono::sys_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970
3572c1d7959SMark de Wever   check(SV("%j='138'\n"), lfmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
3582c1d7959SMark de Wever 
3592c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
3602c1d7959SMark de Wever   check(loc, SV("%j='001'\n"), lfmt, std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3612c1d7959SMark de Wever 
3622c1d7959SMark de Wever   check(
3632c1d7959SMark de Wever       loc, SV("%j='138'\n"), lfmt, std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
3642c1d7959SMark de Wever 
3652c1d7959SMark de Wever   std::locale::global(std::locale::classic());
3662c1d7959SMark de Wever }
3672c1d7959SMark de Wever 
3682c1d7959SMark de Wever template <class CharT>
3692c1d7959SMark de Wever static void test_valid_values_week() {
3702c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
3712c1d7959SMark de Wever 
3722c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");
3732c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");
3742c1d7959SMark de Wever 
3752c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
3762c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
3772c1d7959SMark de Wever 
3782c1d7959SMark de Wever   // Non localized output using C-locale
3792c1d7959SMark de Wever   check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
3802c1d7959SMark de Wever         fmt,
3812c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3822c1d7959SMark de Wever 
3832c1d7959SMark de Wever   check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
3842c1d7959SMark de Wever         fmt,
3852c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
3862c1d7959SMark de Wever 
3872c1d7959SMark de Wever   // Use the global locale (fr_FR)
3882c1d7959SMark de Wever   check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
3892c1d7959SMark de Wever         lfmt,
3902c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
3912c1d7959SMark de Wever 
3922c1d7959SMark de Wever   check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
3932c1d7959SMark de Wever         lfmt,
3942c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
3952c1d7959SMark de Wever 
3962c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
3978f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
3982c1d7959SMark de Wever   check(loc,
3992c1d7959SMark de Wever         SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),
4002c1d7959SMark de Wever         lfmt,
4012c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4022c1d7959SMark de Wever 
4032c1d7959SMark de Wever   check(loc,
4042c1d7959SMark de Wever         SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),
4052c1d7959SMark de Wever         lfmt,
4062c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
4078f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
4082c1d7959SMark de Wever   check(loc,
4092c1d7959SMark de Wever         SV("%U='00'\t%OU='〇'\t%W='00'\t%OW='〇'\n"),
4102c1d7959SMark de Wever         lfmt,
4112c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4122c1d7959SMark de Wever 
4132c1d7959SMark de Wever   check(loc,
4142c1d7959SMark de Wever         SV("%U='20'\t%OU='二十'\t%W='20'\t%OW='二十'\n"),
4152c1d7959SMark de Wever         lfmt,
4162c1d7959SMark de Wever         std::chrono::sys_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033
4178f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
4182c1d7959SMark de Wever   std::locale::global(std::locale::classic());
4192c1d7959SMark de Wever }
4202c1d7959SMark de Wever 
4212c1d7959SMark de Wever template <class CharT>
4222c1d7959SMark de Wever static void test_valid_values_iso_8601_week() {
4232c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
4242c1d7959SMark de Wever 
4252c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");
4262c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");
4272c1d7959SMark de Wever 
4282c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
4292c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
4302c1d7959SMark de Wever 
4312c1d7959SMark de Wever   // Non localized output using C-locale
4322c1d7959SMark de Wever   check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
4332c1d7959SMark de Wever         fmt,
4342c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4352c1d7959SMark de Wever 
4362c1d7959SMark de Wever   check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
4372c1d7959SMark de Wever         fmt,
4382c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
4392c1d7959SMark de Wever 
4402c1d7959SMark de Wever   // Use the global locale (fr_FR)
4412c1d7959SMark de Wever   check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
4422c1d7959SMark de Wever         lfmt,
4432c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4442c1d7959SMark de Wever 
4452c1d7959SMark de Wever   check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
4462c1d7959SMark de Wever         lfmt,
4472c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
4482c1d7959SMark de Wever 
4492c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
4508f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
4512c1d7959SMark de Wever   check(loc,
4522c1d7959SMark de Wever         SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),
4532c1d7959SMark de Wever         lfmt,
4542c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4552c1d7959SMark de Wever 
4562c1d7959SMark de Wever   check(loc,
4572c1d7959SMark de Wever         SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),
4582c1d7959SMark de Wever         lfmt,
4592c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
4608f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
4612c1d7959SMark de Wever   check(loc,
4622c1d7959SMark de Wever         SV("%g='70'\t%G='1970'\t%V='01'\t%OV='一'\n"),
4632c1d7959SMark de Wever         lfmt,
4642c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4652c1d7959SMark de Wever 
4662c1d7959SMark de Wever   check(loc,
4672c1d7959SMark de Wever         SV("%g='09'\t%G='2009'\t%V='07'\t%OV='七'\n"),
4682c1d7959SMark de Wever         lfmt,
4692c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
4708f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
4712c1d7959SMark de Wever 
4722c1d7959SMark de Wever   std::locale::global(std::locale::classic());
4732c1d7959SMark de Wever }
4742c1d7959SMark de Wever 
4752c1d7959SMark de Wever template <class CharT>
4762c1d7959SMark de Wever static void test_valid_values_date() {
4772c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
4782c1d7959SMark de Wever 
4792c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");
4802c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");
4812c1d7959SMark de Wever 
4822c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
4832c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
4842c1d7959SMark de Wever 
4852c1d7959SMark de Wever   // Non localized output using C-locale
4862c1d7959SMark de Wever   check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/70'\t%Ex='01/01/70'\n"),
4872c1d7959SMark de Wever         fmt,
4882c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4892c1d7959SMark de Wever 
4902c1d7959SMark de Wever   check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='02/13/09'\t%Ex='02/13/09'\n"),
4912c1d7959SMark de Wever         fmt,
4922c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
4932c1d7959SMark de Wever 
4942c1d7959SMark de Wever   // Use the global locale (fr_FR)
4958f01029bSMark de Wever #if defined(__APPLE__) || defined(__FreeBSD__)
4962c1d7959SMark de Wever   check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01.01.1970'\t%Ex='01.01.1970'\n"),
4972c1d7959SMark de Wever         lfmt,
4982c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
4992c1d7959SMark de Wever 
5002c1d7959SMark de Wever   check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13.02.2009'\t%Ex='13.02.2009'\n"),
5012c1d7959SMark de Wever         lfmt,
5022c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
5032c1d7959SMark de Wever #else
5042c1d7959SMark de Wever   check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/1970'\t%Ex='01/01/1970'\n"),
5052c1d7959SMark de Wever         lfmt,
5062c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
5072c1d7959SMark de Wever 
5082c1d7959SMark de Wever   check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13/02/2009'\t%Ex='13/02/2009'\n"),
5092c1d7959SMark de Wever         lfmt,
5102c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
5112c1d7959SMark de Wever #endif
5122c1d7959SMark de Wever 
5132c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
5148f01029bSMark de Wever #if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
5152c1d7959SMark de Wever   check(loc,
5162c1d7959SMark de Wever         SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970/01/01'\t%Ex='1970/01/01'\n"),
5172c1d7959SMark de Wever         lfmt,
5182c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
5192c1d7959SMark de Wever 
5202c1d7959SMark de Wever   check(loc,
5212c1d7959SMark de Wever         SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009/02/13'\t%Ex='2009/02/13'\n"),
5222c1d7959SMark de Wever         lfmt,
5232c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
5248f01029bSMark de Wever #else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
5252c1d7959SMark de Wever   check(loc,
5262c1d7959SMark de Wever         SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970年01月01日'\t%Ex='昭和45年01月01日'\n"),
5272c1d7959SMark de Wever         lfmt,
5282c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
5292c1d7959SMark de Wever 
5302c1d7959SMark de Wever   check(loc,
5312c1d7959SMark de Wever         SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009年02月13日'\t%Ex='平成21年02月13日'\n"),
5322c1d7959SMark de Wever         lfmt,
5332c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
5348f01029bSMark de Wever #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)
5352c1d7959SMark de Wever 
5362c1d7959SMark de Wever   std::locale::global(std::locale::classic());
5372c1d7959SMark de Wever }
5382c1d7959SMark de Wever 
5392c1d7959SMark de Wever template <class CharT>
5402c1d7959SMark de Wever static void test_valid_values_time() {
5412c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
5422c1d7959SMark de Wever 
5432c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt = SV(
5442c1d7959SMark de Wever       "{:"
5452c1d7959SMark de Wever       "%%H='%H'%t"
5462c1d7959SMark de Wever       "%%OH='%OH'%t"
5472c1d7959SMark de Wever       "%%I='%I'%t"
5482c1d7959SMark de Wever       "%%OI='%OI'%t"
5492c1d7959SMark de Wever       "%%M='%M'%t"
5502c1d7959SMark de Wever       "%%OM='%OM'%t"
5512c1d7959SMark de Wever       "%%S='%S'%t"
5522c1d7959SMark de Wever       "%%OS='%OS'%t"
5532c1d7959SMark de Wever       "%%p='%p'%t"
5542c1d7959SMark de Wever       "%%R='%R'%t"
5552c1d7959SMark de Wever       "%%T='%T'%t"
5562c1d7959SMark de Wever       "%%r='%r'%t"
5572c1d7959SMark de Wever       "%%X='%X'%t"
5582c1d7959SMark de Wever       "%%EX='%EX'%t"
5592c1d7959SMark de Wever       "%n}");
5602c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV(
5612c1d7959SMark de Wever       "{:L"
5622c1d7959SMark de Wever       "%%H='%H'%t"
5632c1d7959SMark de Wever       "%%OH='%OH'%t"
5642c1d7959SMark de Wever       "%%I='%I'%t"
5652c1d7959SMark de Wever       "%%OI='%OI'%t"
5662c1d7959SMark de Wever       "%%M='%M'%t"
5672c1d7959SMark de Wever       "%%OM='%OM'%t"
5682c1d7959SMark de Wever       "%%S='%S'%t"
5692c1d7959SMark de Wever       "%%OS='%OS'%t"
5702c1d7959SMark de Wever       "%%p='%p'%t"
5712c1d7959SMark de Wever       "%%R='%R'%t"
5722c1d7959SMark de Wever       "%%T='%T'%t"
5732c1d7959SMark de Wever       "%%r='%r'%t"
5742c1d7959SMark de Wever       "%%X='%X'%t"
5752c1d7959SMark de Wever       "%%EX='%EX'%t"
5762c1d7959SMark de Wever       "%n}");
5772c1d7959SMark de Wever 
5782c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
5792c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
5802c1d7959SMark de Wever 
5812c1d7959SMark de Wever   // Non localized output using C-locale
5822c1d7959SMark de Wever   check(SV("%H='00'\t"
5832c1d7959SMark de Wever            "%OH='00'\t"
5842c1d7959SMark de Wever            "%I='12'\t"
5852c1d7959SMark de Wever            "%OI='12'\t"
5862c1d7959SMark de Wever            "%M='00'\t"
5872c1d7959SMark de Wever            "%OM='00'\t"
5882c1d7959SMark de Wever            "%S='00'\t"
5892c1d7959SMark de Wever            "%OS='00'\t"
5902c1d7959SMark de Wever            "%p='AM'\t"
5912c1d7959SMark de Wever            "%R='00:00'\t"
5922c1d7959SMark de Wever            "%T='00:00:00'\t"
5932c1d7959SMark de Wever            "%r='12:00:00 AM'\t"
5942c1d7959SMark de Wever            "%X='00:00:00'\t"
5952c1d7959SMark de Wever            "%EX='00:00:00'\t"
5962c1d7959SMark de Wever            "\n"),
5972c1d7959SMark de Wever         fmt,
5982c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
5992c1d7959SMark de Wever 
6002c1d7959SMark de Wever   check(SV("%H='23'\t"
6012c1d7959SMark de Wever            "%OH='23'\t"
6022c1d7959SMark de Wever            "%I='11'\t"
6032c1d7959SMark de Wever            "%OI='11'\t"
6042c1d7959SMark de Wever            "%M='31'\t"
6052c1d7959SMark de Wever            "%OM='31'\t"
6062c1d7959SMark de Wever            "%S='30.123'\t"
6072c1d7959SMark de Wever            "%OS='30.123'\t"
6082c1d7959SMark de Wever            "%p='PM'\t"
6092c1d7959SMark de Wever            "%R='23:31'\t"
6102c1d7959SMark de Wever            "%T='23:31:30.123'\t"
6112c1d7959SMark de Wever            "%r='11:31:30 PM'\t"
6122c1d7959SMark de Wever            "%X='23:31:30'\t"
6132c1d7959SMark de Wever            "%EX='23:31:30'\t"
6142c1d7959SMark de Wever            "\n"),
6152c1d7959SMark de Wever         fmt,
6162c1d7959SMark de Wever         std::chrono::sys_time<std::chrono::milliseconds>(
6172c1d7959SMark de Wever             1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
6182c1d7959SMark de Wever   // Use the global locale (fr_FR)
6192c1d7959SMark de Wever   check(SV("%H='00'\t"
6202c1d7959SMark de Wever            "%OH='00'\t"
6212c1d7959SMark de Wever            "%I='12'\t"
6222c1d7959SMark de Wever            "%OI='12'\t"
6232c1d7959SMark de Wever            "%M='00'\t"
6242c1d7959SMark de Wever            "%OM='00'\t"
6252c1d7959SMark de Wever            "%S='00'\t"
6262c1d7959SMark de Wever            "%OS='00'\t"
6272c1d7959SMark de Wever #if defined(_AIX)
6282c1d7959SMark de Wever            "%p='AM'\t"
6292c1d7959SMark de Wever #else
6302c1d7959SMark de Wever            "%p=''\t"
6312c1d7959SMark de Wever #endif
6322c1d7959SMark de Wever            "%R='00:00'\t"
6332c1d7959SMark de Wever            "%T='00:00:00'\t"
6342c1d7959SMark de Wever #ifdef _WIN32
6352c1d7959SMark de Wever            "%r='00:00:00'\t"
6362c1d7959SMark de Wever #elif defined(_AIX)
6372c1d7959SMark de Wever            "%r='12:00:00 AM'\t"
6388f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
6392c1d7959SMark de Wever            "%r=''\t"
6402c1d7959SMark de Wever #else
6412c1d7959SMark de Wever            "%r='12:00:00 '\t"
6422c1d7959SMark de Wever #endif
6432c1d7959SMark de Wever            "%X='00:00:00'\t"
6442c1d7959SMark de Wever            "%EX='00:00:00'\t"
6452c1d7959SMark de Wever            "\n"),
6462c1d7959SMark de Wever         lfmt,
6472c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
6482c1d7959SMark de Wever 
6492c1d7959SMark de Wever   check(SV("%H='23'\t"
6502c1d7959SMark de Wever            "%OH='23'\t"
6512c1d7959SMark de Wever            "%I='11'\t"
6522c1d7959SMark de Wever            "%OI='11'\t"
6532c1d7959SMark de Wever            "%M='31'\t"
6542c1d7959SMark de Wever            "%OM='31'\t"
6552c1d7959SMark de Wever            "%S='30,123'\t"
6562c1d7959SMark de Wever            "%OS='30,123'\t"
6572c1d7959SMark de Wever #if defined(_AIX)
6582c1d7959SMark de Wever            "%p='PM'\t"
6592c1d7959SMark de Wever #else
6602c1d7959SMark de Wever            "%p=''\t"
6612c1d7959SMark de Wever #endif
6622c1d7959SMark de Wever            "%R='23:31'\t"
6632c1d7959SMark de Wever            "%T='23:31:30,123'\t"
6642c1d7959SMark de Wever #ifdef _WIN32
6652c1d7959SMark de Wever            "%r='23:31:30'\t"
6662c1d7959SMark de Wever #elif defined(_AIX)
6672c1d7959SMark de Wever            "%r='11:31:30 PM'\t"
6688f01029bSMark de Wever #elif defined(__APPLE__) || defined(__FreeBSD__)
6692c1d7959SMark de Wever            "%r=''\t"
6702c1d7959SMark de Wever #else
6712c1d7959SMark de Wever            "%r='11:31:30 '\t"
6722c1d7959SMark de Wever #endif
6732c1d7959SMark de Wever            "%X='23:31:30'\t"
6742c1d7959SMark de Wever            "%EX='23:31:30'\t"
6752c1d7959SMark de Wever            "\n"),
6762c1d7959SMark de Wever         lfmt,
6772c1d7959SMark de Wever         std::chrono::sys_time<std::chrono::milliseconds>(
6782c1d7959SMark de Wever             1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
6792c1d7959SMark de Wever 
6801403080aSMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.
6818f01029bSMark de Wever #if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
6822c1d7959SMark de Wever   check(loc,
6832c1d7959SMark de Wever         SV("%H='00'\t"
6842c1d7959SMark de Wever            "%OH='00'\t"
6852c1d7959SMark de Wever            "%I='12'\t"
6862c1d7959SMark de Wever            "%OI='12'\t"
6872c1d7959SMark de Wever            "%M='00'\t"
6882c1d7959SMark de Wever            "%OM='00'\t"
6892c1d7959SMark de Wever            "%S='00'\t"
6902c1d7959SMark de Wever            "%OS='00'\t"
6912c1d7959SMark de Wever #  if defined(__APPLE__)
6922c1d7959SMark de Wever            "%p='AM'\t"
6932c1d7959SMark de Wever #  else
6942c1d7959SMark de Wever            "%p='午前'\t"
6952c1d7959SMark de Wever #  endif
6962c1d7959SMark de Wever            "%R='00:00'\t"
6972c1d7959SMark de Wever            "%T='00:00:00'\t"
6988f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
6992c1d7959SMark de Wever #    if defined(__APPLE__)
7002c1d7959SMark de Wever            "%r='12:00:00 AM'\t"
7018f01029bSMark de Wever #    else
7028f01029bSMark de Wever            "%r='12:00:00 午前'\t"
7038f01029bSMark de Wever #    endif
7042c1d7959SMark de Wever            "%X='00時00分00秒'\t"
7052c1d7959SMark de Wever            "%EX='00時00分00秒'\t"
7061403080aSMark de Wever #  elif defined(_WIN32)
7071403080aSMark de Wever            "%r='0:00:00'\t"
7081403080aSMark de Wever            "%X='0:00:00'\t"
7091403080aSMark de Wever            "%EX='0:00:00'\t"
7102c1d7959SMark de Wever #  else
7112c1d7959SMark de Wever            "%r='午前12:00:00'\t"
7122c1d7959SMark de Wever            "%X='00:00:00'\t"
7132c1d7959SMark de Wever            "%EX='00:00:00'\t"
7142c1d7959SMark de Wever #  endif
7152c1d7959SMark de Wever            "\n"),
7162c1d7959SMark de Wever         lfmt,
7172c1d7959SMark de Wever         std::chrono::hh_mm_ss(0s));
7182c1d7959SMark de Wever 
7192c1d7959SMark de Wever   check(loc,
7202c1d7959SMark de Wever         SV("%H='23'\t"
7212c1d7959SMark de Wever            "%OH='23'\t"
7222c1d7959SMark de Wever            "%I='11'\t"
7232c1d7959SMark de Wever            "%OI='11'\t"
7242c1d7959SMark de Wever            "%M='31'\t"
7252c1d7959SMark de Wever            "%OM='31'\t"
7262c1d7959SMark de Wever            "%S='30.123'\t"
7272c1d7959SMark de Wever            "%OS='30.123'\t"
7282c1d7959SMark de Wever #  if defined(__APPLE__)
7292c1d7959SMark de Wever            "%p='PM'\t"
7302c1d7959SMark de Wever #  else
7312c1d7959SMark de Wever            "%p='午後'\t"
7322c1d7959SMark de Wever #  endif
7332c1d7959SMark de Wever            "%R='23:31'\t"
7342c1d7959SMark de Wever            "%T='23:31:30.123'\t"
7358f01029bSMark de Wever #  if defined(__APPLE__) || defined(__FreeBSD__)
7362c1d7959SMark de Wever #    if defined(__APPLE__)
7372c1d7959SMark de Wever            "%r='11:31:30 PM'\t"
7388f01029bSMark de Wever #    else
7398f01029bSMark de Wever            "%r='11:31:30 午後'\t"
7408f01029bSMark de Wever #    endif
7412c1d7959SMark de Wever            "%X='23時31分30秒'\t"
7422c1d7959SMark de Wever            "%EX='23時31分30秒'\t"
7431403080aSMark de Wever #  elif defined(_WIN32)
7441403080aSMark de Wever            "%r='23:31:30'\t"
7451403080aSMark de Wever            "%X='23:31:30'\t"
7461403080aSMark de Wever            "%EX='23:31:30'\t"
7472c1d7959SMark de Wever #  else
7482c1d7959SMark de Wever            "%r='午後11:31:30'\t"
7492c1d7959SMark de Wever            "%X='23:31:30'\t"
7502c1d7959SMark de Wever            "%EX='23:31:30'\t"
7512c1d7959SMark de Wever #  endif
7522c1d7959SMark de Wever            "\n"),
7532c1d7959SMark de Wever         lfmt,
7542c1d7959SMark de Wever         std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));
7558f01029bSMark de Wever #else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
7562c1d7959SMark de Wever   check(loc,
7572c1d7959SMark de Wever         SV("%H='00'\t"
7582c1d7959SMark de Wever            "%OH='〇'\t"
7592c1d7959SMark de Wever            "%I='12'\t"
7602c1d7959SMark de Wever            "%OI='十二'\t"
7612c1d7959SMark de Wever            "%M='00'\t"
7622c1d7959SMark de Wever            "%OM='〇'\t"
7632c1d7959SMark de Wever            "%S='00'\t"
7642c1d7959SMark de Wever            "%OS='〇'\t"
7652c1d7959SMark de Wever            "%p='午前'\t"
7662c1d7959SMark de Wever            "%R='00:00'\t"
7672c1d7959SMark de Wever            "%T='00:00:00'\t"
7682c1d7959SMark de Wever            "%r='午前12時00分00秒'\t"
7692c1d7959SMark de Wever            "%X='00時00分00秒'\t"
7702c1d7959SMark de Wever            "%EX='00時00分00秒'\t"
7712c1d7959SMark de Wever            "\n"),
7722c1d7959SMark de Wever         lfmt,
7732c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
7742c1d7959SMark de Wever 
7752c1d7959SMark de Wever   check(loc,
7762c1d7959SMark de Wever         SV("%H='23'\t"
7772c1d7959SMark de Wever            "%OH='二十三'\t"
7782c1d7959SMark de Wever            "%I='11'\t"
7792c1d7959SMark de Wever            "%OI='十一'\t"
7802c1d7959SMark de Wever            "%M='31'\t"
7812c1d7959SMark de Wever            "%OM='三十一'\t"
7822c1d7959SMark de Wever            "%S='30.123'\t"
7832c1d7959SMark de Wever            "%OS='三十.123'\t"
7842c1d7959SMark de Wever            "%p='午後'\t"
7852c1d7959SMark de Wever            "%R='23:31'\t"
7862c1d7959SMark de Wever            "%T='23:31:30.123'\t"
7872c1d7959SMark de Wever            "%r='午後11時31分30秒'\t"
7882c1d7959SMark de Wever            "%X='23時31分30秒'\t"
7892c1d7959SMark de Wever            "%EX='23時31分30秒'\t"
7902c1d7959SMark de Wever            "\n"),
7912c1d7959SMark de Wever         lfmt,
7922c1d7959SMark de Wever         std::chrono::sys_time<std::chrono::milliseconds>(
7932c1d7959SMark de Wever             1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009
7948f01029bSMark de Wever #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)
7952c1d7959SMark de Wever 
7962c1d7959SMark de Wever   std::locale::global(std::locale::classic());
7972c1d7959SMark de Wever }
7982c1d7959SMark de Wever 
7992c1d7959SMark de Wever template <class CharT>
8002c1d7959SMark de Wever static void test_valid_values_date_time() {
8012c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
8022c1d7959SMark de Wever 
8032c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%c='%c'%t%%Ec='%Ec'%n}");
8042c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%c='%c'%t%%Ec='%Ec'%n}");
8052c1d7959SMark de Wever 
8062c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
8072c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
8082c1d7959SMark de Wever 
8092c1d7959SMark de Wever   // Non localized output using C-locale
8102c1d7959SMark de Wever   check(SV("%c='Thu Jan  1 00:00:00 1970'\t%Ec='Thu Jan  1 00:00:00 1970'\n"),
8112c1d7959SMark de Wever         fmt,
8122c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8132c1d7959SMark de Wever 
8142c1d7959SMark de Wever   check(SV("%c='Fri Feb 13 23:31:30 2009'\t%Ec='Fri Feb 13 23:31:30 2009'\n"),
8152c1d7959SMark de Wever         fmt,
8162c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8172c1d7959SMark de Wever 
8182c1d7959SMark de Wever   // Use the global locale (fr_FR)
8192c1d7959SMark de Wever   check(
8202c1d7959SMark de Wever // https://sourceware.org/bugzilla/show_bug.cgi?id=24054
821e4d4cfa5SLei Huang #if defined(__powerpc__) && defined(__linux__)
822e4d4cfa5SLei Huang       SV("%c='jeu. 01 janv. 1970 00:00:00 UTC'\t%Ec='jeu. 01 janv. 1970 00:00:00 UTC'\n"),
823e4d4cfa5SLei Huang #elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
8242c1d7959SMark de Wever       SV("%c='jeu. 01 janv. 1970 00:00:00 GMT'\t%Ec='jeu. 01 janv. 1970 00:00:00 GMT'\n"),
8252c1d7959SMark de Wever #elif defined(_AIX)
8262c1d7959SMark de Wever       SV("%c=' 1 janvier 1970 à 00:00:00 UTC'\t%Ec=' 1 janvier 1970 à 00:00:00 UTC'\n"),
8272c1d7959SMark de Wever #elif defined(__APPLE__)
8282c1d7959SMark de Wever       SV("%c='Jeu  1 jan 00:00:00 1970'\t%Ec='Jeu  1 jan 00:00:00 1970'\n"),
8291403080aSMark de Wever #elif defined(_WIN32)
8301403080aSMark de Wever       SV("%c='01/01/1970 00:00:00'\t%Ec='01/01/1970 00:00:00'\n"),
8318f01029bSMark de Wever #elif defined(__FreeBSD__)
8328f01029bSMark de Wever       SV("%c='jeu.  1 janv. 00:00:00 1970'\t%Ec='jeu.  1 janv. 00:00:00 1970'\n"),
8332c1d7959SMark de Wever #else
8342c1d7959SMark de Wever       SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"),
8352c1d7959SMark de Wever #endif
8362c1d7959SMark de Wever       lfmt,
8372c1d7959SMark de Wever       std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8382c1d7959SMark de Wever 
8392c1d7959SMark de Wever   check(
8402c1d7959SMark de Wever // https://sourceware.org/bugzilla/show_bug.cgi?id=24054
841e4d4cfa5SLei Huang #if defined(__powerpc__) && defined(__linux__)
842e4d4cfa5SLei Huang       SV("%c='ven. 13 févr. 2009 23:31:30 UTC'\t%Ec='ven. 13 févr. 2009 23:31:30 UTC'\n"),
843e4d4cfa5SLei Huang #elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29
8442c1d7959SMark de Wever       SV("%c='ven. 13 févr. 2009 23:31:30 GMT'\t%Ec='ven. 13 févr. 2009 23:31:30 GMT'\n"),
8452c1d7959SMark de Wever #elif defined(_AIX)
8462c1d7959SMark de Wever       SV("%c='13 février 2009 à 23:31:30 UTC'\t%Ec='13 février 2009 à 23:31:30 UTC'\n"),
8472c1d7959SMark de Wever #elif defined(__APPLE__)
8482c1d7959SMark de Wever       SV("%c='Ven 13 fév 23:31:30 2009'\t%Ec='Ven 13 fév 23:31:30 2009'\n"),
8491403080aSMark de Wever #elif defined(_WIN32)
8501403080aSMark de Wever       SV("%c='13/02/2009 23:31:30'\t%Ec='13/02/2009 23:31:30'\n"),
8518f01029bSMark de Wever #elif defined(__FreeBSD__)
8528f01029bSMark de Wever       SV("%c='ven. 13 févr. 23:31:30 2009'\t%Ec='ven. 13 févr. 23:31:30 2009'\n"),
8532c1d7959SMark de Wever #else
8542c1d7959SMark de Wever       SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"),
8552c1d7959SMark de Wever #endif
8562c1d7959SMark de Wever       lfmt,
8572c1d7959SMark de Wever       std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8582c1d7959SMark de Wever 
8592c1d7959SMark de Wever   // Use supplied locale (ja_JP). This locale has a different alternate.a
8608f01029bSMark de Wever #if defined(__APPLE__) || defined(__FreeBSD__)
8612c1d7959SMark de Wever   check(loc,
8622c1d7959SMark de Wever         SV("%c='木  1/ 1 00:00:00 1970'\t%Ec='木  1/ 1 00:00:00 1970'\n"),
8632c1d7959SMark de Wever         lfmt,
8642c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8652c1d7959SMark de Wever   check(loc,
8662c1d7959SMark de Wever         SV("%c='金  2/13 23:31:30 2009'\t%Ec='金  2/13 23:31:30 2009'\n"),
8672c1d7959SMark de Wever         lfmt,
8682c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8698f01029bSMark de Wever #elif defined(_AIX)                                // defined(__APPLE__)|| defined(__FreeBSD__)
8702c1d7959SMark de Wever   check(loc,
8712c1d7959SMark de Wever         SV("%c='1970年01月 1日 00:00:00 UTC'\t%Ec='1970年01月 1日 00:00:00 UTC'\n"),
8722c1d7959SMark de Wever         lfmt,
8732c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8742c1d7959SMark de Wever   check(loc,
8752c1d7959SMark de Wever         SV("%c='2009年02月13日 23:31:30 UTC'\t%Ec='2009年02月13日 23:31:30 UTC'\n"),
8762c1d7959SMark de Wever         lfmt,
8772c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8788f01029bSMark de Wever #elif defined(_WIN32)                              // defined(__APPLE__)|| defined(__FreeBSD__)
8791403080aSMark de Wever   check(loc,
8801403080aSMark de Wever         SV("%c='1970/01/01 0:00:00'\t%Ec='1970/01/01 0:00:00'\n"),
8811403080aSMark de Wever         lfmt,
8821403080aSMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8831403080aSMark de Wever   check(loc,
8841403080aSMark de Wever         SV("%c='2009/02/13 23:31:30'\t%Ec='2009/02/13 23:31:30'\n"),
8851403080aSMark de Wever         lfmt,
8861403080aSMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8878f01029bSMark de Wever #else                                              // defined(__APPLE__)|| defined(__FreeBSD__)
8882c1d7959SMark de Wever   check(loc,
8892c1d7959SMark de Wever         SV("%c='1970年01月01日 00時00分00秒'\t%Ec='昭和45年01月01日 00時00分00秒'\n"),
8902c1d7959SMark de Wever         lfmt,
8912c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
8922c1d7959SMark de Wever 
8932c1d7959SMark de Wever   check(loc,
8942c1d7959SMark de Wever         SV("%c='2009年02月13日 23時31分30秒'\t%Ec='平成21年02月13日 23時31分30秒'\n"),
8952c1d7959SMark de Wever         lfmt,
8962c1d7959SMark de Wever         std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009
8978f01029bSMark de Wever #endif                                             // defined(__APPLE__)|| defined(__FreeBSD__)
8982c1d7959SMark de Wever 
8992c1d7959SMark de Wever   std::locale::global(std::locale::classic());
9002c1d7959SMark de Wever }
9012c1d7959SMark de Wever 
9022c1d7959SMark de Wever template <class CharT>
9032c1d7959SMark de Wever static void test_valid_values_time_zone() {
9042c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
9052c1d7959SMark de Wever 
9062c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> fmt  = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
9072c1d7959SMark de Wever   constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
9082c1d7959SMark de Wever 
9092c1d7959SMark de Wever   const std::locale loc(LOCALE_ja_JP_UTF_8);
9102c1d7959SMark de Wever   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
9112c1d7959SMark de Wever 
9122c1d7959SMark de Wever   // Non localized output using C-locale
913a6fcbcceSMark de Wever   check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
9142c1d7959SMark de Wever         fmt,
9152c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
9162c1d7959SMark de Wever 
9172c1d7959SMark de Wever   // Use the global locale (fr_FR)
918a6fcbcceSMark de Wever   check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
9192c1d7959SMark de Wever         lfmt,
9202c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
9212c1d7959SMark de Wever 
922a6fcbcceSMark de Wever   // Use supplied locale (ja_JP).
9232c1d7959SMark de Wever   check(loc,
924a6fcbcceSMark de Wever         SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),
9252c1d7959SMark de Wever         lfmt,
9262c1d7959SMark de Wever         std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970
9272c1d7959SMark de Wever 
9282c1d7959SMark de Wever   std::locale::global(std::locale::classic());
9292c1d7959SMark de Wever }
9302c1d7959SMark de Wever 
9312c1d7959SMark de Wever template <class CharT>
9322c1d7959SMark de Wever static void test_valid_values() {
9332c1d7959SMark de Wever   test_valid_values_year<CharT>();
9342c1d7959SMark de Wever   test_valid_values_month<CharT>();
9352c1d7959SMark de Wever   test_valid_values_day<CharT>();
9362c1d7959SMark de Wever   test_valid_values_weekday<CharT>();
9372c1d7959SMark de Wever   test_valid_values_day_of_year<CharT>();
9382c1d7959SMark de Wever   test_valid_values_week<CharT>();
9392c1d7959SMark de Wever   test_valid_values_iso_8601_week<CharT>();
9402c1d7959SMark de Wever   test_valid_values_date<CharT>();
9412c1d7959SMark de Wever   test_valid_values_time<CharT>();
9422c1d7959SMark de Wever   test_valid_values_date_time<CharT>();
9432c1d7959SMark de Wever   test_valid_values_time_zone<CharT>();
9442c1d7959SMark de Wever }
9452c1d7959SMark de Wever 
9462c1d7959SMark de Wever template <class CharT>
9472c1d7959SMark de Wever static void test() {
9482c1d7959SMark de Wever   using namespace std::literals::chrono_literals;
9492c1d7959SMark de Wever 
9502c1d7959SMark de Wever   test_no_chrono_specs<CharT>();
9512c1d7959SMark de Wever   test_valid_values<CharT>();
9522c1d7959SMark de Wever   check_invalid_types<CharT>(
9532c1d7959SMark de Wever       {SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("c"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("F"),  SV("g"),
9542c1d7959SMark de Wever        SV("G"),  SV("h"),  SV("H"),  SV("I"),  SV("j"),  SV("m"),  SV("M"),  SV("p"),  SV("r"),  SV("R"),  SV("S"),
9552c1d7959SMark de Wever        SV("T"),  SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("X"),  SV("y"),  SV("Y"),  SV("z"),
9562c1d7959SMark de Wever        SV("Z"),  SV("Ec"), SV("EC"), SV("Ex"), SV("EX"), SV("Ey"), SV("EY"), SV("Ez"), SV("Od"), SV("Oe"), SV("OH"),
9572c1d7959SMark de Wever        SV("OI"), SV("Om"), SV("OM"), SV("OS"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"), SV("Oz")},
9582c1d7959SMark de Wever       std::chrono::sys_seconds(0s));
9592c1d7959SMark de Wever 
960402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::sys_seconds(0s));
961402eb2efSMark de Wever   check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::sys_seconds(0s));
962402eb2efSMark de Wever   check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::sys_seconds(0s));
9632c1d7959SMark de Wever   check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::sys_seconds(0s));
9642c1d7959SMark de Wever   check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::sys_seconds(0s));
9652c1d7959SMark de Wever 
9662c1d7959SMark de Wever   // Precision not allowed
967402eb2efSMark de Wever   check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::sys_seconds(0s));
9682c1d7959SMark de Wever }
9692c1d7959SMark de Wever 
9702c1d7959SMark de Wever int main(int, char**) {
9712c1d7959SMark de Wever   test<char>();
9722c1d7959SMark de Wever 
9732c1d7959SMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS
9742c1d7959SMark de Wever   test<wchar_t>();
9752c1d7959SMark de Wever #endif
9762c1d7959SMark de Wever 
9772c1d7959SMark de Wever   return 0;
9782c1d7959SMark de Wever }
979