1005 lines · cpp
1//===----------------------------------------------------------------------===//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7 8// UNSUPPORTED: c++03, c++11, c++14, c++179// UNSUPPORTED: no-filesystem, no-localization, no-tzdb10// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME11 12// TODO FMT This test should not require std::to_chars(floating-point)13// XFAIL: availability-fp_to_chars-missing14 15// XFAIL: libcpp-has-no-experimental-tzdb16// XFAIL: availability-tzdb-missing17 18// REQUIRES: locale.fr_FR.UTF-819// REQUIRES: locale.ja_JP.UTF-820 21// <chrono>22 23// template<class Duration, class charT>24// struct formatter<chrono::utc_time<Duration>, charT>;25 26#include <chrono>27#include <format>28 29#include <cassert>30#include <concepts>31#include <locale>32#include <iostream>33#include <type_traits>34 35#include "formatter_tests.h"36#include "make_string.h"37#include "platform_support.h" // locale name macros38#include "test_macros.h"39 40template <class CharT>41static void test_no_chrono_specs() {42 using namespace std::literals::chrono_literals;43 44 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));45 46 // Non localized output47 48 // [time.syn]49 // using nanoseconds = duration<signed integer type of at least 64 bits, nano>;50 // using microseconds = duration<signed integer type of at least 55 bits, micro>;51 // using milliseconds = duration<signed integer type of at least 45 bits, milli>;52 // using seconds = duration<signed integer type of at least 35 bits>;53 // using minutes = duration<signed integer type of at least 29 bits, ratio< 60>>;54 // using hours = duration<signed integer type of at least 23 bits, ratio<3600>>;55 check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::utc_seconds(-17'179'869'184s)); // Minimum value for 35 bits.56 check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::utc_seconds(-2'147'483'648s));57 58 check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::utc_seconds(-24h));59 check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::utc_seconds(-18h));60 check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::utc_seconds(-12h));61 check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::utc_seconds(-6h));62 check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::utc_seconds(-1s));63 64 check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::utc_seconds(0s));65 check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::utc_seconds(946'684'800s + 22s));66 check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::utc_seconds(946'688'523s + 22s));67 68 check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::utc_seconds(2'147'483'647s + 27s));69 check(SV("2514-05-30 01:53:03"),70 SV("{}"),71 std::chrono::utc_seconds(17'179'869'183s + 27s)); // Maximum value for 35 bits.72 73 check(SV("2000-01-01 01:02:03.123"),74 SV("{}"),75 std::chrono::utc_time<std::chrono::milliseconds>(946'688'523'123ms + 22s));76 77 std::locale::global(std::locale::classic());78}79 80template <class CharT>81static void test_valid_values_year() {82 using namespace std::literals::chrono_literals;83 84 constexpr std::basic_string_view<CharT> fmt =85 SV("{:%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");86 constexpr std::basic_string_view<CharT> lfmt =87 SV("{:L%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");88 89 const std::locale loc(LOCALE_ja_JP_UTF_8);90 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));91 92 // Non localized output using C-locale93 check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),94 fmt,95 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 197096 97 check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),98 fmt,99 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009100 101 // Use the global locale (fr_FR)102 check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),103 lfmt,104 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970105 106 check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),107 lfmt,108 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009109 110 // Use supplied locale (ja_JP). This locale has a different alternate.111#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)112 check(loc,113 SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),114 lfmt,115 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970116 117 check(loc,118 SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),119 lfmt,120 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009121#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)122 check(loc,123 SV("%C='19'\t%EC='昭和'\t%y='70'\t%Oy='七十'\t%Ey='45'\t%Y='1970'\t%EY='昭和45年'\n"),124 lfmt,125 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970126 127 check(loc,128 SV("%C='20'\t%EC='平成'\t%y='09'\t%Oy='九'\t%Ey='21'\t%Y='2009'\t%EY='平成21年'\n"),129 lfmt,130 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009131#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)132 133 std::locale::global(std::locale::classic());134}135 136template <class CharT>137static void test_valid_values_month() {138 using namespace std::literals::chrono_literals;139 140 constexpr std::basic_string_view<CharT> fmt = SV("{:%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");141 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");142 143 const std::locale loc(LOCALE_ja_JP_UTF_8);144 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));145 146 // Non localized output using C-locale147 check(SV("%b='Jan'\t%h='Jan'\t%B='January'\t%m='01'\t%Om='01'\n"),148 fmt,149 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970150 151 check(SV("%b='May'\t%h='May'\t%B='May'\t%m='05'\t%Om='05'\n"),152 fmt,153 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033154 155 // Use the global locale (fr_FR)156#if defined(__APPLE__)157 check(SV("%b='jan'\t%h='jan'\t%B='janvier'\t%m='01'\t%Om='01'\n"),158 lfmt,159 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970160#else161 check(SV("%b='janv.'\t%h='janv.'\t%B='janvier'\t%m='01'\t%Om='01'\n"),162 lfmt,163 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970164#endif165 166 check(SV("%b='mai'\t%h='mai'\t%B='mai'\t%m='05'\t%Om='05'\n"),167 lfmt,168 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033169 170 // Use supplied locale (ja_JP). This locale has a different alternate.171#ifdef _WIN32172 check(loc,173 SV("%b='1'\t%h='1'\t%B='1月'\t%m='01'\t%Om='01'\n"),174 lfmt,175 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970176 177 check(loc,178 SV("%b='5'\t%h='5'\t%B='5月'\t%m='05'\t%Om='05'\n"),179 lfmt,180 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033181#elif defined(_AIX) // _WIN32182 check(loc,183 SV("%b='1月'\t%h='1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),184 lfmt,185 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970186 187 check(loc,188 SV("%b='5月'\t%h='5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),189 lfmt,190 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033191#elif defined(__APPLE__) // _WIN32192 check(loc,193 SV("%b=' 1'\t%h=' 1'\t%B='1月'\t%m='01'\t%Om='01'\n"),194 lfmt,195 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970196 197 check(loc,198 SV("%b=' 5'\t%h=' 5'\t%B='5月'\t%m='05'\t%Om='05'\n"),199 lfmt,200 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033201#elif defined(__FreeBSD__) // _WIN32202 check(loc,203 SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),204 lfmt,205 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970206 207 check(loc,208 SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),209 lfmt,210 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033211#else // _WIN32212 check(loc,213 SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='一'\n"),214 lfmt,215 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970216 217 check(loc,218 SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='五'\n"),219 lfmt,220 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033221#endif // _WIN32222 223 std::locale::global(std::locale::classic());224}225 226template <class CharT>227static void test_valid_values_day() {228 using namespace std::literals::chrono_literals;229 230 constexpr std::basic_string_view<CharT> fmt = SV("{:%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");231 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");232 233 const std::locale loc(LOCALE_ja_JP_UTF_8);234 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));235 236 // Non localized output using C-locale237 check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),238 fmt,239 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970240 241 check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),242 fmt,243 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009244 245 // Use the global locale (fr_FR)246 check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),247 lfmt,248 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970249 250 check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),251 lfmt,252 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009253 254 // Use supplied locale (ja_JP). This locale has a different alternate.255#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)256 check(loc,257 SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),258 lfmt,259 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970260 261 check(loc,262 SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),263 lfmt,264 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009265#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)266 check(loc,267 SV("%d='01'\t%Od='一'\t%e=' 1'\t%Oe='一'\n"),268 lfmt,269 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970270 271 check(loc,272 SV("%d='13'\t%Od='十三'\t%e='13'\t%Oe='十三'\n"),273 lfmt,274 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009275 276#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)277 278 std::locale::global(std::locale::classic());279}280 281template <class CharT>282static void test_valid_values_weekday() {283 using namespace std::literals::chrono_literals;284 285 constexpr std::basic_string_view<CharT> fmt =286 SV("{:%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");287 constexpr std::basic_string_view<CharT> lfmt =288 SV("{:L%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");289 290 const std::locale loc(LOCALE_ja_JP_UTF_8);291 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));292 293 // Non localized output using C-locale294 check(SV("%a='Thu'\t%A='Thursday'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),295 fmt,296 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970297 298 check(SV("%a='Sun'\t%A='Sunday'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),299 fmt,300 std::chrono::utc_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106301 302 // Use the global locale (fr_FR)303#if defined(__APPLE__)304 check(SV("%a='Jeu'\t%A='Jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),305 lfmt,306 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970307 308 check(SV("%a='Dim'\t%A='Dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),309 lfmt,310 std::chrono::utc_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106311#else312 check(SV("%a='jeu.'\t%A='jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),313 lfmt,314 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970315 316 check(SV("%a='dim.'\t%A='dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),317 lfmt,318 std::chrono::utc_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106319#endif320 321 // Use supplied locale (ja_JP).322 // This locale has a different alternate, but not on all platforms323#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)324 check(loc,325 SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),326 lfmt,327 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970328 329 check(loc,330 SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),331 lfmt,332 std::chrono::utc_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106333#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)334 check(loc,335 SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\n"),336 lfmt,337 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970338 339 check(loc,340 SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\n"),341 lfmt,342 std::chrono::utc_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106343#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)344 345 std::locale::global(std::locale::classic());346}347 348template <class CharT>349static void test_valid_values_day_of_year() {350 using namespace std::literals::chrono_literals;351 352 constexpr std::basic_string_view<CharT> fmt = SV("{:%%j='%j'%n}");353 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%j='%j'%n}");354 355 const std::locale loc(LOCALE_ja_JP_UTF_8);356 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));357 358 // Non localized output using C-locale359 check(SV("%j='001'\n"), fmt, std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970360 check(SV("%j='138'\n"), fmt, std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033361 362 // Use the global locale (fr_FR)363 check(SV("%j='001'\n"), lfmt, std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970364 check(SV("%j='138'\n"), lfmt, std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033365 366 // Use supplied locale (ja_JP). This locale has a different alternate.367 check(loc, SV("%j='001'\n"), lfmt, std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970368 369 check(370 loc, SV("%j='138'\n"), lfmt, std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033371 372 std::locale::global(std::locale::classic());373}374 375template <class CharT>376static void test_valid_values_week() {377 using namespace std::literals::chrono_literals;378 379 constexpr std::basic_string_view<CharT> fmt = SV("{:%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");380 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");381 382 const std::locale loc(LOCALE_ja_JP_UTF_8);383 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));384 385 // Non localized output using C-locale386 check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),387 fmt,388 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970389 390 check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),391 fmt,392 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033393 394 // Use the global locale (fr_FR)395 check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),396 lfmt,397 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970398 399 check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),400 lfmt,401 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033402 403 // Use supplied locale (ja_JP). This locale has a different alternate.404#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)405 check(loc,406 SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),407 lfmt,408 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970409 410 check(loc,411 SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),412 lfmt,413 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033414#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)415 check(loc,416 SV("%U='00'\t%OU='〇'\t%W='00'\t%OW='〇'\n"),417 lfmt,418 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970419 420 check(loc,421 SV("%U='20'\t%OU='二十'\t%W='20'\t%OW='二十'\n"),422 lfmt,423 std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033424#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)425 std::locale::global(std::locale::classic());426}427 428template <class CharT>429static void test_valid_values_iso_8601_week() {430 using namespace std::literals::chrono_literals;431 432 constexpr std::basic_string_view<CharT> fmt = SV("{:%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");433 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");434 435 const std::locale loc(LOCALE_ja_JP_UTF_8);436 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));437 438 // Non localized output using C-locale439 check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),440 fmt,441 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970442 443 check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),444 fmt,445 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009446 447 // Use the global locale (fr_FR)448 check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),449 lfmt,450 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970451 452 check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),453 lfmt,454 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009455 456 // Use supplied locale (ja_JP). This locale has a different alternate.457#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)458 check(loc,459 SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),460 lfmt,461 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970462 463 check(loc,464 SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),465 lfmt,466 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009467#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)468 check(loc,469 SV("%g='70'\t%G='1970'\t%V='01'\t%OV='一'\n"),470 lfmt,471 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970472 473 check(loc,474 SV("%g='09'\t%G='2009'\t%V='07'\t%OV='七'\n"),475 lfmt,476 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009477#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)478 479 std::locale::global(std::locale::classic());480}481 482template <class CharT>483static void test_valid_values_date() {484 using namespace std::literals::chrono_literals;485 486 constexpr std::basic_string_view<CharT> fmt = SV("{:%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");487 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");488 489 const std::locale loc(LOCALE_ja_JP_UTF_8);490 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));491 492 // Non localized output using C-locale493 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/70'\t%Ex='01/01/70'\n"),494 fmt,495 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970496 497 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='02/13/09'\t%Ex='02/13/09'\n"),498 fmt,499 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009500 501 // Use the global locale (fr_FR)502#if defined(__APPLE__) || defined(__FreeBSD__)503 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01.01.1970'\t%Ex='01.01.1970'\n"),504 lfmt,505 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970506 507 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13.02.2009'\t%Ex='13.02.2009'\n"),508 lfmt,509 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009510#else511 check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/1970'\t%Ex='01/01/1970'\n"),512 lfmt,513 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970514 515 check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13/02/2009'\t%Ex='13/02/2009'\n"),516 lfmt,517 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009518#endif519 520 // Use supplied locale (ja_JP). This locale has a different alternate.521#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)522 check(loc,523 SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970/01/01'\t%Ex='1970/01/01'\n"),524 lfmt,525 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970526 527 check(loc,528 SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009/02/13'\t%Ex='2009/02/13'\n"),529 lfmt,530 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009531#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)532 check(loc,533 SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970年01月01日'\t%Ex='昭和45年01月01日'\n"),534 lfmt,535 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970536 537 check(loc,538 SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009年02月13日'\t%Ex='平成21年02月13日'\n"),539 lfmt,540 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009541#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)542 543 std::locale::global(std::locale::classic());544}545 546template <class CharT>547static void test_valid_values_time() {548 using namespace std::literals::chrono_literals;549 550 constexpr std::basic_string_view<CharT> fmt = SV(551 "{:"552 "%%H='%H'%t"553 "%%OH='%OH'%t"554 "%%I='%I'%t"555 "%%OI='%OI'%t"556 "%%M='%M'%t"557 "%%OM='%OM'%t"558 "%%S='%S'%t"559 "%%OS='%OS'%t"560 "%%p='%p'%t"561 "%%R='%R'%t"562 "%%T='%T'%t"563 "%%r='%r'%t"564 "%%X='%X'%t"565 "%%EX='%EX'%t"566 "%n}");567 constexpr std::basic_string_view<CharT> lfmt = SV(568 "{:L"569 "%%H='%H'%t"570 "%%OH='%OH'%t"571 "%%I='%I'%t"572 "%%OI='%OI'%t"573 "%%M='%M'%t"574 "%%OM='%OM'%t"575 "%%S='%S'%t"576 "%%OS='%OS'%t"577 "%%p='%p'%t"578 "%%R='%R'%t"579 "%%T='%T'%t"580 "%%r='%r'%t"581 "%%X='%X'%t"582 "%%EX='%EX'%t"583 "%n}");584 585 const std::locale loc(LOCALE_ja_JP_UTF_8);586 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));587 588 // Non localized output using C-locale589 check(SV("%H='00'\t"590 "%OH='00'\t"591 "%I='12'\t"592 "%OI='12'\t"593 "%M='00'\t"594 "%OM='00'\t"595 "%S='00'\t"596 "%OS='00'\t"597 "%p='AM'\t"598 "%R='00:00'\t"599 "%T='00:00:00'\t"600 "%r='12:00:00 AM'\t"601 "%X='00:00:00'\t"602 "%EX='00:00:00'\t"603 "\n"),604 fmt,605 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970606 607 check(SV("%H='23'\t"608 "%OH='23'\t"609 "%I='11'\t"610 "%OI='11'\t"611 "%M='31'\t"612 "%OM='31'\t"613 "%S='30.123'\t"614 "%OS='30.123'\t"615 "%p='PM'\t"616 "%R='23:31'\t"617 "%T='23:31:30.123'\t"618 "%r='11:31:30 PM'\t"619 "%X='23:31:30'\t"620 "%EX='23:31:30'\t"621 "\n"),622 fmt,623 std::chrono::utc_time<std::chrono::milliseconds>(624 1'234'567'890'123ms + 24s)); // 23:31:30 UTC on Friday, 13 February 2009625 // Use the global locale (fr_FR)626 check(SV("%H='00'\t"627 "%OH='00'\t"628 "%I='12'\t"629 "%OI='12'\t"630 "%M='00'\t"631 "%OM='00'\t"632 "%S='00'\t"633 "%OS='00'\t"634#if defined(_AIX)635 "%p='AM'\t"636#else637 "%p=''\t"638#endif639 "%R='00:00'\t"640 "%T='00:00:00'\t"641#ifdef _WIN32642 "%r='00:00:00'\t"643#elif defined(_AIX)644 "%r='12:00:00 AM'\t"645#elif defined(__APPLE__) || defined(__FreeBSD__)646 "%r=''\t"647#else648 "%r='12:00:00 '\t"649#endif650 "%X='00:00:00'\t"651 "%EX='00:00:00'\t"652 "\n"),653 lfmt,654 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970655 656 check(SV("%H='23'\t"657 "%OH='23'\t"658 "%I='11'\t"659 "%OI='11'\t"660 "%M='31'\t"661 "%OM='31'\t"662 "%S='30,123'\t"663 "%OS='30,123'\t"664#if defined(_AIX)665 "%p='PM'\t"666#else667 "%p=''\t"668#endif669 "%R='23:31'\t"670 "%T='23:31:30,123'\t"671#ifdef _WIN32672 "%r='23:31:30'\t"673#elif defined(_AIX)674 "%r='11:31:30 PM'\t"675#elif defined(__APPLE__) || defined(__FreeBSD__)676 "%r=''\t"677#else678 "%r='11:31:30 '\t"679#endif680 "%X='23:31:30'\t"681 "%EX='23:31:30'\t"682 "\n"),683 lfmt,684 std::chrono::utc_time<std::chrono::milliseconds>(685 1'234'567'890'123ms + 24s)); // 23:31:30 UTC on Friday, 13 February 2009686 687 // Use supplied locale (ja_JP). This locale has a different alternate.688#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)689 check(loc,690 SV("%H='00'\t"691 "%OH='00'\t"692 "%I='12'\t"693 "%OI='12'\t"694 "%M='00'\t"695 "%OM='00'\t"696 "%S='00'\t"697 "%OS='00'\t"698# if defined(__APPLE__)699 "%p='AM'\t"700# else701 "%p='午前'\t"702# endif703 "%R='00:00'\t"704 "%T='00:00:00'\t"705# if defined(__APPLE__) || defined(__FreeBSD__)706# if defined(__APPLE__)707 "%r='12:00:00 AM'\t"708# else709 "%r='12:00:00 午前'\t"710# endif711 "%X='00時00分00秒'\t"712 "%EX='00時00分00秒'\t"713# elif defined(_WIN32)714 "%r='0:00:00'\t"715 "%X='0:00:00'\t"716 "%EX='0:00:00'\t"717# else718 "%r='午前12:00:00'\t"719 "%X='00:00:00'\t"720 "%EX='00:00:00'\t"721# endif722 "\n"),723 lfmt,724 std::chrono::hh_mm_ss(0s));725 726 check(loc,727 SV("%H='23'\t"728 "%OH='23'\t"729 "%I='11'\t"730 "%OI='11'\t"731 "%M='31'\t"732 "%OM='31'\t"733 "%S='30.123'\t"734 "%OS='30.123'\t"735# if defined(__APPLE__)736 "%p='PM'\t"737# else738 "%p='午後'\t"739# endif740 "%R='23:31'\t"741 "%T='23:31:30.123'\t"742# if defined(__APPLE__) || defined(__FreeBSD__)743# if defined(__APPLE__)744 "%r='11:31:30 PM'\t"745# else746 "%r='11:31:30 午後'\t"747# endif748 "%X='23時31分30秒'\t"749 "%EX='23時31分30秒'\t"750# elif defined(_WIN32)751 "%r='23:31:30'\t"752 "%X='23:31:30'\t"753 "%EX='23:31:30'\t"754# else755 "%r='午後11:31:30'\t"756 "%X='23:31:30'\t"757 "%EX='23:31:30'\t"758# endif759 "\n"),760 lfmt,761 std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));762#else // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)763 check(loc,764 SV("%H='00'\t"765 "%OH='〇'\t"766 "%I='12'\t"767 "%OI='十二'\t"768 "%M='00'\t"769 "%OM='〇'\t"770 "%S='00'\t"771 "%OS='〇'\t"772 "%p='午前'\t"773 "%R='00:00'\t"774 "%T='00:00:00'\t"775 "%r='午前12時00分00秒'\t"776 "%X='00時00分00秒'\t"777 "%EX='00時00分00秒'\t"778 "\n"),779 lfmt,780 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970781 782 check(loc,783 SV("%H='23'\t"784 "%OH='二十三'\t"785 "%I='11'\t"786 "%OI='十一'\t"787 "%M='31'\t"788 "%OM='三十一'\t"789 "%S='30.123'\t"790 "%OS='三十.123'\t"791 "%p='午後'\t"792 "%R='23:31'\t"793 "%T='23:31:30.123'\t"794 "%r='午後11時31分30秒'\t"795 "%X='23時31分30秒'\t"796 "%EX='23時31分30秒'\t"797 "\n"),798 lfmt,799 std::chrono::utc_time<std::chrono::milliseconds>(800 1'234'567'890'123ms + 24s)); // 23:31:30 UTC on Friday, 13 February 2009801#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)802 803 std::locale::global(std::locale::classic());804}805 806template <class CharT>807static void test_valid_values_date_time() {808 using namespace std::literals::chrono_literals;809 810 constexpr std::basic_string_view<CharT> fmt = SV("{:%%c='%c'%t%%Ec='%Ec'%n}");811 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%c='%c'%t%%Ec='%Ec'%n}");812 813 const std::locale loc(LOCALE_ja_JP_UTF_8);814 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));815 816 // Non localized output using C-locale817 check(SV("%c='Thu Jan 1 00:00:00 1970'\t%Ec='Thu Jan 1 00:00:00 1970'\n"),818 fmt,819 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970820 821 check(SV("%c='Fri Feb 13 23:31:30 2009'\t%Ec='Fri Feb 13 23:31:30 2009'\n"),822 fmt,823 std::chrono::utc_seconds(1'234'567'890s + 24s)); // 23:31:30 UTC on Friday, 13 February 2009824 825 // Use the global locale (fr_FR)826 check(827// https://sourceware.org/bugzilla/show_bug.cgi?id=24054828#if defined(__powerpc__) && defined(__linux__)829 SV("%c='jeu. 01 janv. 1970 00:00:00 UTC'\t%Ec='jeu. 01 janv. 1970 00:00:00 UTC'\n"),830#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29831 SV("%c='jeu. 01 janv. 1970 00:00:00 GMT'\t%Ec='jeu. 01 janv. 1970 00:00:00 GMT'\n"),832#elif defined(_AIX)833 SV("%c=' 1 janvier 1970 à 00:00:00 UTC'\t%Ec=' 1 janvier 1970 à 00:00:00 UTC'\n"),834#elif defined(__APPLE__)835 SV("%c='Jeu 1 jan 00:00:00 1970'\t%Ec='Jeu 1 jan 00:00:00 1970'\n"),836#elif defined(_WIN32)837 SV("%c='01/01/1970 00:00:00'\t%Ec='01/01/1970 00:00:00'\n"),838#elif defined(__FreeBSD__)839 SV("%c='jeu. 1 janv. 00:00:00 1970'\t%Ec='jeu. 1 janv. 00:00:00 1970'\n"),840#else841 SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"),842#endif843 lfmt,844 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970845 846 check(847// https://sourceware.org/bugzilla/show_bug.cgi?id=24054848#if defined(__powerpc__) && defined(__linux__)849 SV("%c='ven. 13 févr. 2009 23:31:30 UTC'\t%Ec='ven. 13 févr. 2009 23:31:30 UTC'\n"),850#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29851 SV("%c='ven. 13 févr. 2009 23:31:30 GMT'\t%Ec='ven. 13 févr. 2009 23:31:30 GMT'\n"),852#elif defined(_AIX)853 SV("%c='13 février 2009 à 23:31:30 UTC'\t%Ec='13 février 2009 à 23:31:30 UTC'\n"),854#elif defined(__APPLE__)855 SV("%c='Ven 13 fév 23:31:30 2009'\t%Ec='Ven 13 fév 23:31:30 2009'\n"),856#elif defined(_WIN32)857 SV("%c='13/02/2009 23:31:30'\t%Ec='13/02/2009 23:31:30'\n"),858#elif defined(__FreeBSD__)859 SV("%c='ven. 13 févr. 23:31:30 2009'\t%Ec='ven. 13 févr. 23:31:30 2009'\n"),860#else861 SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"),862#endif863 lfmt,864 std::chrono::utc_seconds(1'234'567'890s + 24s)); // 23:31:30 UTC on Friday, 13 February 2009865 866 // Use supplied locale (ja_JP). This locale has a different alternate.a867#if defined(__APPLE__) || defined(__FreeBSD__)868 check(loc,869 SV("%c='木 1/ 1 00:00:00 1970'\t%Ec='木 1/ 1 00:00:00 1970'\n"),870 lfmt,871 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970872 check(loc,873 SV("%c='金 2/13 23:31:30 2009'\t%Ec='金 2/13 23:31:30 2009'\n"),874 lfmt,875 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009876#elif defined(_AIX) // defined(__APPLE__)|| defined(__FreeBSD__)877 check(loc,878 SV("%c='1970年01月 1日 00:00:00 UTC'\t%Ec='1970年01月 1日 00:00:00 UTC'\n"),879 lfmt,880 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970881 check(loc,882 SV("%c='2009年02月13日 23:31:30 UTC'\t%Ec='2009年02月13日 23:31:30 UTC'\n"),883 lfmt,884 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009885#elif defined(_WIN32) // defined(__APPLE__)|| defined(__FreeBSD__)886 check(loc,887 SV("%c='1970/01/01 0:00:00'\t%Ec='1970/01/01 0:00:00'\n"),888 lfmt,889 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970890 check(loc,891 SV("%c='2009/02/13 23:31:30'\t%Ec='2009/02/13 23:31:30'\n"),892 lfmt,893 std::chrono::utc_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009894#else // defined(__APPLE__)|| defined(__FreeBSD__)895 check(loc,896 SV("%c='1970年01月01日 00時00分00秒'\t%Ec='昭和45年01月01日 00時00分00秒'\n"),897 lfmt,898 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970899 900 check(loc,901 SV("%c='2009年02月13日 23時31分30秒'\t%Ec='平成21年02月13日 23時31分30秒'\n"),902 lfmt,903 std::chrono::utc_seconds(1'234'567'890s + 24s)); // 23:31:30 UTC on Friday, 13 February 2009904#endif // defined(__APPLE__)|| defined(__FreeBSD__)905 906 std::locale::global(std::locale::classic());907}908 909template <class CharT>910static void test_valid_values_time_zone() {911 using namespace std::literals::chrono_literals;912 913 constexpr std::basic_string_view<CharT> fmt = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");914 constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");915 916 const std::locale loc(LOCALE_ja_JP_UTF_8);917 std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));918 919 // Non localized output using C-locale920 check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),921 fmt,922 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970923 924 // Use the global locale (fr_FR)925 check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),926 lfmt,927 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970928 929 // Use supplied locale (ja_JP).930 check(loc,931 SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),932 lfmt,933 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970934 935 std::locale::global(std::locale::classic());936}937 938template <class CharT>939static void test_utc_transitions() {940 using namespace std::literals::chrono_literals;941 942 constexpr std::basic_string_view<CharT> fmt = SV("{:%F %T}");943 check(SV("1972-06-30 23:59:59"), fmt, std::chrono::utc_seconds(78'796'799s));944 check(SV("1972-06-30 23:59:60"), fmt, std::chrono::utc_seconds(78'796'800s));945 check(SV("1972-07-01 00:00:00"), fmt, std::chrono::utc_seconds(78'796'801s));946 947 check(SV("1972-12-31 23:59:59"), fmt, std::chrono::utc_seconds(94'694'400s));948 check(SV("1972-12-31 23:59:60"), fmt, std::chrono::utc_seconds(94'694'401s));949 check(SV("1973-01-01 00:00:00"), fmt, std::chrono::utc_seconds(94'694'402s));950}951 952template <class CharT>953static void test_valid_values() {954 test_valid_values_year<CharT>();955 test_valid_values_month<CharT>();956 test_valid_values_day<CharT>();957 test_valid_values_weekday<CharT>();958 test_valid_values_day_of_year<CharT>();959 test_valid_values_week<CharT>();960 test_valid_values_iso_8601_week<CharT>();961 test_valid_values_date<CharT>();962 test_valid_values_time<CharT>();963 test_valid_values_date_time<CharT>();964 test_valid_values_time_zone<CharT>();965 966 test_utc_transitions<CharT>();967}968 969// In order to have the UTC seconds the number of leap seconds need to be970// included in the UTC time. The number of leap seconds for times far in the971// future are not yet known and may change in the future.972template <class CharT>973static void test() {974 using namespace std::literals::chrono_literals;975 976 test_no_chrono_specs<CharT>();977 test_valid_values<CharT>();978 check_invalid_types<CharT>(979 {SV("a"), SV("A"), SV("b"), SV("B"), SV("c"), SV("C"), SV("d"), SV("D"), SV("e"), SV("F"), SV("g"),980 SV("G"), SV("h"), SV("H"), SV("I"), SV("j"), SV("m"), SV("M"), SV("p"), SV("r"), SV("R"), SV("S"),981 SV("T"), SV("u"), SV("U"), SV("V"), SV("w"), SV("W"), SV("x"), SV("X"), SV("y"), SV("Y"), SV("z"),982 SV("Z"), SV("Ec"), SV("EC"), SV("Ex"), SV("EX"), SV("Ey"), SV("EY"), SV("Ez"), SV("Od"), SV("Oe"), SV("OH"),983 SV("OI"), SV("Om"), SV("OM"), SV("OS"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"), SV("Oz")},984 std::chrono::utc_seconds(0s));985 986 check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::utc_seconds(0s));987 check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::utc_seconds(0s));988 check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::utc_seconds(0s));989 check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::utc_seconds(0s));990 check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::utc_seconds(0s));991 992 // Precision not allowed993 check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::utc_seconds(0s));994}995 996int main(int, char**) {997 test<char>();998 999#ifndef TEST_HAS_NO_WIDE_CHARACTERS1000 test<wchar_t>();1001#endif1002 1003 return 0;1004}1005