brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.7 KiB · e258c41 Raw
968 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710// UNSUPPORTED: no-localization11// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME12 13// TODO FMT This test should not require std::to_chars(floating-point)14// XFAIL: availability-fp_to_chars-missing15 16// REQUIRES: locale.fr_FR.UTF-817// REQUIRES: locale.ja_JP.UTF-818 19// <chrono>20//21// template<class charT> struct formatter<chrono::file_time, charT>;22 23#include <chrono>24#include <format>25 26#include <cassert>27#include <concepts>28#include <locale>29#include <iostream>30#include <type_traits>31 32#include "formatter_tests.h"33#include "make_string.h"34#include "platform_support.h" // locale name macros35#include "test_macros.h"36 37// Modeled after the system clock's usings, this make adapting the38// tests easier.39template <class Duration>40using file_time    = std::chrono::time_point<std::chrono::file_clock, Duration>;41using file_seconds = file_time<std::chrono::seconds>;42using file_days    = file_time<std::chrono::days>;43 44template <class CharT>45static void test_no_chrono_specs() {46  using namespace std::literals::chrono_literals;47 48  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));49 50  // Non localized output51 52  // [time.syn]53  //   using nanoseconds  = duration<signed integer type of at least 64 bits, nano>;54  //   using microseconds = duration<signed integer type of at least 55 bits, micro>;55  //   using milliseconds = duration<signed integer type of at least 45 bits, milli>;56  //   using seconds      = duration<signed integer type of at least 35 bits>;57  //   using minutes      = duration<signed integer type of at least 29 bits, ratio<  60>>;58  //   using hours        = duration<signed integer type of at least 23 bits, ratio<3600>>;59  check(SV("1425-08-04 22:06:56"), SV("{}"), file_seconds(-17'179'869'184s)); // Minimum value for 35 bits.60  check(SV("1901-12-13 20:45:52"), SV("{}"), file_seconds(-2'147'483'648s));61 62  check(SV("1969-12-31 00:00:00"), SV("{}"), file_seconds(-24h));63  check(SV("1969-12-31 06:00:00"), SV("{}"), file_seconds(-18h));64  check(SV("1969-12-31 12:00:00"), SV("{}"), file_seconds(-12h));65  check(SV("1969-12-31 18:00:00"), SV("{}"), file_seconds(-6h));66  check(SV("1969-12-31 23:59:59"), SV("{}"), file_seconds(-1s));67 68  check(SV("1970-01-01 00:00:00"), SV("{}"), file_seconds(0s));69  check(SV("2000-01-01 00:00:00"), SV("{}"), file_seconds(946'684'800s));70  check(SV("2000-01-01 01:02:03"), SV("{}"), file_seconds(946'688'523s));71 72  check(SV("2038-01-19 03:14:07"), SV("{}"), file_seconds(2'147'483'647s));73  check(SV("2514-05-30 01:53:03"), SV("{}"), file_seconds(17'179'869'183s)); // Maximum value for 35 bits.74 75  check(SV("2000-01-01 01:02:03.123"), SV("{}"), file_time<std::chrono::milliseconds>(946'688'523'123ms));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        file_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        file_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        file_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        file_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 113  check(loc,114        SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),115        lfmt,116        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970117 118  check(loc,119        SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),120        lfmt,121        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009122#else                                  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)|| defined(__FreeBSD__)123 124  check(loc,125        SV("%C='19'\t%EC='昭和'\t%y='70'\t%Oy='七十'\t%Ey='45'\t%Y='1970'\t%EY='昭和45年'\n"),126        lfmt,127        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970128 129  check(loc,130        SV("%C='20'\t%EC='平成'\t%y='09'\t%Oy='九'\t%Ey='21'\t%Y='2009'\t%EY='平成21年'\n"),131        lfmt,132        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009133#endif                                 // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)|| defined(__FreeBSD__)134 135  std::locale::global(std::locale::classic());136}137 138template <class CharT>139static void test_valid_values_month() {140  using namespace std::literals::chrono_literals;141 142  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");143  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");144 145  const std::locale loc(LOCALE_ja_JP_UTF_8);146  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));147 148  // Non localized output using C-locale149  check(SV("%b='Jan'\t%h='Jan'\t%B='January'\t%m='01'\t%Om='01'\n"),150        fmt,151        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970152 153  check(SV("%b='May'\t%h='May'\t%B='May'\t%m='05'\t%Om='05'\n"),154        fmt,155        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033156 157  // Use the global locale (fr_FR)158#if defined(__APPLE__)159  check(SV("%b='jan'\t%h='jan'\t%B='janvier'\t%m='01'\t%Om='01'\n"),160        lfmt,161        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970162#else163  check(SV("%b='janv.'\t%h='janv.'\t%B='janvier'\t%m='01'\t%Om='01'\n"),164        lfmt,165        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970166#endif167 168  check(SV("%b='mai'\t%h='mai'\t%B='mai'\t%m='05'\t%Om='05'\n"),169        lfmt,170        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033171 172  // Use supplied locale (ja_JP). This locale has a different alternate.173#ifdef _WIN32174  check(loc,175        SV("%b='1'\t%h='1'\t%B='1月'\t%m='01'\t%Om='01'\n"),176        lfmt,177        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970178 179  check(loc,180        SV("%b='5'\t%h='5'\t%B='5月'\t%m='05'\t%Om='05'\n"),181        lfmt,182        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033183#elif defined(_AIX)                    // _WIN32184  check(loc,185        SV("%b='1月'\t%h='1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),186        lfmt,187        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970188 189  check(loc,190        SV("%b='5月'\t%h='5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),191        lfmt,192        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033193#elif defined(__APPLE__)               // _WIN32194  check(loc,195        SV("%b=' 1'\t%h=' 1'\t%B='1月'\t%m='01'\t%Om='01'\n"),196        lfmt,197        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970198 199  check(loc,200        SV("%b=' 5'\t%h=' 5'\t%B='5月'\t%m='05'\t%Om='05'\n"),201        lfmt,202        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033203#elif defined(__FreeBSD__)             // _WIN32204  check(loc,205        SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),206        lfmt,207        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970208 209  check(loc,210        SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),211        lfmt,212        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033213#else                                  // _WIN32214  check(loc,215        SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='一'\n"),216        lfmt,217        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970218 219  check(loc,220        SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='五'\n"),221        lfmt,222        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033223#endif                                 // _WIN32224 225  std::locale::global(std::locale::classic());226}227 228template <class CharT>229static void test_valid_values_day() {230  using namespace std::literals::chrono_literals;231 232  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");233  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");234 235  const std::locale loc(LOCALE_ja_JP_UTF_8);236  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));237 238  // Non localized output using C-locale239  check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"), fmt,240        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970241 242  check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),243        fmt,244        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009245 246  // Use the global locale (fr_FR)247  check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"), lfmt,248        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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        file_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, file_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970360  check(SV("%j='138'\n"), fmt, file_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, file_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970364  check(SV("%j='138'\n"), lfmt, file_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, file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970368 369  check(loc, SV("%j='138'\n"), lfmt, file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033370 371  std::locale::global(std::locale::classic());372}373 374template <class CharT>375static void test_valid_values_week() {376  using namespace std::literals::chrono_literals;377 378  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");379  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");380 381  const std::locale loc(LOCALE_ja_JP_UTF_8);382  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));383 384  // Non localized output using C-locale385  check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"), fmt,386        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970387 388  check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),389        fmt,390        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033391 392  // Use the global locale (fr_FR)393  check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"), lfmt,394        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970395 396  check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),397        lfmt,398        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033399 400  // Use supplied locale (ja_JP). This locale has a different alternate.401#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)402  check(loc,403        SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),404        lfmt,405        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970406 407  check(loc,408        SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),409        lfmt,410        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033411#else                                  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)412  check(loc,413        SV("%U='00'\t%OU='〇'\t%W='00'\t%OW='〇'\n"),414        lfmt,415        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970416 417  check(loc,418        SV("%U='20'\t%OU='二十'\t%W='20'\t%OW='二十'\n"),419        lfmt,420        file_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033421#endif                                 // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)422  std::locale::global(std::locale::classic());423}424 425template <class CharT>426static void test_valid_values_iso_8601_week() {427  using namespace std::literals::chrono_literals;428 429  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");430  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");431 432  const std::locale loc(LOCALE_ja_JP_UTF_8);433  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));434 435  // Non localized output using C-locale436  check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"), fmt,437        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970438 439  check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),440        fmt,441        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009442 443  // Use the global locale (fr_FR)444  check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"), lfmt,445        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970446 447  check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),448        lfmt,449        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009450 451  // Use supplied locale (ja_JP). This locale has a different alternate.452#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)453  check(loc,454        SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),455        lfmt,456        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970457 458  check(loc,459        SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),460        lfmt,461        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009462#else                                  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)463  check(loc,464        SV("%g='70'\t%G='1970'\t%V='01'\t%OV='一'\n"),465        lfmt,466        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970467 468  check(loc,469        SV("%g='09'\t%G='2009'\t%V='07'\t%OV='七'\n"),470        lfmt,471        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009472#endif                                 // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)473 474  std::locale::global(std::locale::classic());475}476 477template <class CharT>478static void test_valid_values_date() {479  using namespace std::literals::chrono_literals;480 481  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");482  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");483 484  const std::locale loc(LOCALE_ja_JP_UTF_8);485  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));486 487  // Non localized output using C-locale488  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/70'\t%Ex='01/01/70'\n"),489        fmt,490        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970491 492  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='02/13/09'\t%Ex='02/13/09'\n"),493        fmt,494        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009495 496  // Use the global locale (fr_FR)497#if defined(__APPLE__) || defined(__FreeBSD__)498  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01.01.1970'\t%Ex='01.01.1970'\n"),499        lfmt,500        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970501 502  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13.02.2009'\t%Ex='13.02.2009'\n"),503        lfmt,504        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009505#else506  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/1970'\t%Ex='01/01/1970'\n"),507        lfmt,508        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970509 510  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13/02/2009'\t%Ex='13/02/2009'\n"),511        lfmt,512        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009513#endif514 515  // Use supplied locale (ja_JP). This locale has a different alternate.516#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)517  check(loc,518        SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970/01/01'\t%Ex='1970/01/01'\n"),519        lfmt,520        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970521 522  check(loc,523        SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009/02/13'\t%Ex='2009/02/13'\n"),524        lfmt,525        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009526#else                                  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)527  check(loc,528        SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970年01月01日'\t%Ex='昭和45年01月01日'\n"),529        lfmt,530        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970531 532  check(loc,533        SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009年02月13日'\t%Ex='平成21年02月13日'\n"),534        lfmt,535        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009536#endif                                 // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)537 538  std::locale::global(std::locale::classic());539}540 541template <class CharT>542static void test_valid_values_time() {543  using namespace std::literals::chrono_literals;544 545  constexpr std::basic_string_view<CharT> fmt = SV(546      "{:"547      "%%H='%H'%t"548      "%%OH='%OH'%t"549      "%%I='%I'%t"550      "%%OI='%OI'%t"551      "%%M='%M'%t"552      "%%OM='%OM'%t"553      "%%S='%S'%t"554      "%%OS='%OS'%t"555      "%%p='%p'%t"556      "%%R='%R'%t"557      "%%T='%T'%t"558      "%%r='%r'%t"559      "%%X='%X'%t"560      "%%EX='%EX'%t"561      "%n}");562  constexpr std::basic_string_view<CharT> lfmt = SV(563      "{:L"564      "%%H='%H'%t"565      "%%OH='%OH'%t"566      "%%I='%I'%t"567      "%%OI='%OI'%t"568      "%%M='%M'%t"569      "%%OM='%OM'%t"570      "%%S='%S'%t"571      "%%OS='%OS'%t"572      "%%p='%p'%t"573      "%%R='%R'%t"574      "%%T='%T'%t"575      "%%r='%r'%t"576      "%%X='%X'%t"577      "%%EX='%EX'%t"578      "%n}");579 580  const std::locale loc(LOCALE_ja_JP_UTF_8);581  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));582 583  // Non localized output using C-locale584  check(SV("%H='00'\t"585           "%OH='00'\t"586           "%I='12'\t"587           "%OI='12'\t"588           "%M='00'\t"589           "%OM='00'\t"590           "%S='00'\t"591           "%OS='00'\t"592           "%p='AM'\t"593           "%R='00:00'\t"594           "%T='00:00:00'\t"595           "%r='12:00:00 AM'\t"596           "%X='00:00:00'\t"597           "%EX='00:00:00'\t"598           "\n"),599        fmt,600        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970601 602  check(SV("%H='23'\t"603           "%OH='23'\t"604           "%I='11'\t"605           "%OI='11'\t"606           "%M='31'\t"607           "%OM='31'\t"608           "%S='30.123'\t"609           "%OS='30.123'\t"610           "%p='PM'\t"611           "%R='23:31'\t"612           "%T='23:31:30.123'\t"613           "%r='11:31:30 PM'\t"614           "%X='23:31:30'\t"615           "%EX='23:31:30'\t"616           "\n"),617        fmt,618        std::chrono::sys_time<std::chrono::milliseconds>(619            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009620  // Use the global locale (fr_FR)621  check(SV("%H='00'\t"622           "%OH='00'\t"623           "%I='12'\t"624           "%OI='12'\t"625           "%M='00'\t"626           "%OM='00'\t"627           "%S='00'\t"628           "%OS='00'\t"629#if defined(_AIX)630           "%p='AM'\t"631#else632           "%p=''\t"633#endif634           "%R='00:00'\t"635           "%T='00:00:00'\t"636#ifdef _WIN32637           "%r='00:00:00'\t"638#elif defined(_AIX)639           "%r='12:00:00 AM'\t"640#elif defined(__APPLE__) || defined(__FreeBSD__)641           "%r=''\t"642#else643           "%r='12:00:00 '\t"644#endif645           "%X='00:00:00'\t"646           "%EX='00:00:00'\t"647           "\n"),648        lfmt,649        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970650 651  check(SV("%H='23'\t"652           "%OH='23'\t"653           "%I='11'\t"654           "%OI='11'\t"655           "%M='31'\t"656           "%OM='31'\t"657           "%S='30,123'\t"658           "%OS='30,123'\t"659#if defined(_AIX)660           "%p='PM'\t"661#else662           "%p=''\t"663#endif664           "%R='23:31'\t"665           "%T='23:31:30,123'\t"666#ifdef _WIN32667           "%r='23:31:30'\t"668#elif defined(_AIX)669           "%r='11:31:30 PM'\t"670#elif defined(__APPLE__) || defined(__FreeBSD__)671           "%r=''\t"672#elif defined(_WIN32)673           "%r='23:31:30 '\t"674#else675           "%r='11:31:30 '\t"676#endif677           "%X='23:31:30'\t"678           "%EX='23:31:30'\t"679           "\n"),680        lfmt,681        std::chrono::sys_time<std::chrono::milliseconds>(682            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009683 684  // Use supplied locale (ja_JP). This locale has a different alternate.a685#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)686  check(loc,687        SV("%H='00'\t"688           "%OH='00'\t"689           "%I='12'\t"690           "%OI='12'\t"691           "%M='00'\t"692           "%OM='00'\t"693           "%S='00'\t"694           "%OS='00'\t"695           "%p='午前'\t"696           "%R='00:00'\t"697           "%T='00:00:00'\t"698#  if defined(__APPLE__) || defined(__FreeBSD__)699           "%r='12:00:00 午前'\t"700           "%X='00時00分00秒'\t"701           "%EX='00時00分00秒'\t"702#  elif defined(_WIN32)703           "%r='0:00:00'\t"704           "%X='0:00:00'\t"705           "%EX='0:00:00'\t"706#  else707           "%r='午前12:00:00'\t"708           "%X='00:00:00'\t"709           "%EX='00:00:00'\t"710#  endif711           "\n"),712        lfmt,713        std::chrono::hh_mm_ss(0s));714 715  check(loc,716        SV("%H='23'\t"717           "%OH='23'\t"718           "%I='11'\t"719           "%OI='11'\t"720           "%M='31'\t"721           "%OM='31'\t"722           "%S='30.123'\t"723           "%OS='30.123'\t"724           "%p='午後'\t"725           "%R='23:31'\t"726           "%T='23:31:30.123'\t"727#  if defined(__APPLE__) || defined(__FreeBSD__)728           "%r='11:31:30 午後'\t"729           "%X='23時31分30秒'\t"730           "%EX='23時31分30秒'\t"731#  elif defined(_WIN32)732           "%r='23:31:30'\t"733           "%X='23:31:30'\t"734           "%EX='23:31:30'\t"735#  else736           "%r='午後11:31:30'\t"737           "%X='23:31:30'\t"738           "%EX='23:31:30'\t"739#  endif740           "\n"),741        lfmt,742        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));743#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)744  check(loc,745        SV("%H='00'\t"746           "%OH='〇'\t"747           "%I='12'\t"748           "%OI='十二'\t"749           "%M='00'\t"750           "%OM='〇'\t"751           "%S='00'\t"752           "%OS='〇'\t"753           "%p='午前'\t"754           "%R='00:00'\t"755           "%T='00:00:00'\t"756           "%r='午前12時00分00秒'\t"757           "%X='00時00分00秒'\t"758           "%EX='00時00分00秒'\t"759           "\n"),760        lfmt,761        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970762 763  check(loc,764        SV("%H='23'\t"765           "%OH='二十三'\t"766           "%I='11'\t"767           "%OI='十一'\t"768           "%M='31'\t"769           "%OM='三十一'\t"770           "%S='30.123'\t"771           "%OS='三十.123'\t"772           "%p='午後'\t"773           "%R='23:31'\t"774           "%T='23:31:30.123'\t"775           "%r='午後11時31分30秒'\t"776           "%X='23時31分30秒'\t"777           "%EX='23時31分30秒'\t"778           "\n"),779        lfmt,780        std::chrono::sys_time<std::chrono::milliseconds>(781            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009782#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)783 784  std::locale::global(std::locale::classic());785}786 787template <class CharT>788static void test_valid_values_date_time() {789  using namespace std::literals::chrono_literals;790 791  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%c='%c'%t%%Ec='%Ec'%n}");792  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%c='%c'%t%%Ec='%Ec'%n}");793 794  const std::locale loc(LOCALE_ja_JP_UTF_8);795  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));796 797  // Non localized output using C-locale798  check(SV("%c='Thu Jan  1 00:00:00 1970'\t%Ec='Thu Jan  1 00:00:00 1970'\n"),799        fmt,800        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970801 802  check(SV("%c='Fri Feb 13 23:31:30 2009'\t%Ec='Fri Feb 13 23:31:30 2009'\n"),803        fmt,804        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009805 806  // Use the global locale (fr_FR)807  check(808// https://sourceware.org/bugzilla/show_bug.cgi?id=24054809#if defined(__powerpc__) && defined(__linux__)810      SV("%c='jeu. 01 janv. 1970 00:00:00 UTC'\t%Ec='jeu. 01 janv. 1970 00:00:00 UTC'\n"),811#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29812      SV("%c='jeu. 01 janv. 1970 00:00:00 GMT'\t%Ec='jeu. 01 janv. 1970 00:00:00 GMT'\n"),813#elif defined(_AIX)814      SV("%c=' 1 janvier 1970 à 00:00:00 UTC'\t%Ec=' 1 janvier 1970 à 00:00:00 UTC'\n"),815#elif defined(__APPLE__)816      SV("%c='Jeu  1 jan 00:00:00 1970'\t%Ec='Jeu  1 jan 00:00:00 1970'\n"),817#elif defined(_WIN32)818      SV("%c='01/01/1970 00:00:00'\t%Ec='01/01/1970 00:00:00'\n"),819#elif defined(__FreeBSD__)820      SV("%c='jeu.  1 janv. 00:00:00 1970'\t%Ec='jeu.  1 janv. 00:00:00 1970'\n"),821#else822      SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"),823#endif824      lfmt,825      file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970826 827  check(828// https://sourceware.org/bugzilla/show_bug.cgi?id=24054829#if defined(__powerpc__) && defined(__linux__)830      SV("%c='ven. 13 févr. 2009 23:31:30 UTC'\t%Ec='ven. 13 févr. 2009 23:31:30 UTC'\n"),831#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29832      SV("%c='ven. 13 févr. 2009 23:31:30 GMT'\t%Ec='ven. 13 févr. 2009 23:31:30 GMT'\n"),833#elif defined(_AIX)834      SV("%c='13 février 2009 à 23:31:30 UTC'\t%Ec='13 février 2009 à 23:31:30 UTC'\n"),835#elif defined(__APPLE__)836      SV("%c='Ven 13 fév 23:31:30 2009'\t%Ec='Ven 13 fév 23:31:30 2009'\n"),837#elif defined(_WIN32)838      SV("%c='13/02/2009 23:31:30'\t%Ec='13/02/2009 23:31:30'\n"),839#elif defined(__FreeBSD__)840      SV("%c='ven. 13 févr. 23:31:30 2009'\t%Ec='ven. 13 févr. 23:31:30 2009'\n"),841#else842      SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"),843#endif844      lfmt,845      file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009846 847  // Use supplied locale (ja_JP). This locale has a different alternate.a848#if defined(__APPLE__) || defined(__FreeBSD__)849  check(loc,850        SV("%c='木  1/ 1 00:00:00 1970'\t%Ec='木  1/ 1 00:00:00 1970'\n"),851        lfmt,852        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970853  check(loc,854        SV("%c='金  2/13 23:31:30 2009'\t%Ec='金  2/13 23:31:30 2009'\n"),855        lfmt,856        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009857#elif defined(_AIX)                    // defined(__APPLE__)|| defined(__FreeBSD__)858  check(loc,859        SV("%c='1970年01月 1日 00:00:00 UTC'\t%Ec='1970年01月 1日 00:00:00 UTC'\n"),860        lfmt,861        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970862  check(loc,863        SV("%c='2009年02月13日 23:31:30 UTC'\t%Ec='2009年02月13日 23:31:30 UTC'\n"),864        lfmt,865        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009866#elif defined(_WIN32)                  // defined(__APPLE__)|| defined(__FreeBSD__)867  check(loc,868        SV("%c='1970/01/01 0:00:00'\t%Ec='1970/01/01 0:00:00'\n"),869        lfmt,870        std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970871  check(loc,872        SV("%c='2009/02/13 23:31:30'\t%Ec='2009/02/13 23:31:30'\n"),873        lfmt,874        std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009875#else                                  // defined(__APPLE__)|| defined(__FreeBSD__)876  check(loc,877        SV("%c='1970年01月01日 00時00分00秒'\t%Ec='昭和45年01月01日 00時00分00秒'\n"),878        lfmt,879        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970880 881  check(loc,882        SV("%c='2009年02月13日 23時31分30秒'\t%Ec='平成21年02月13日 23時31分30秒'\n"),883        lfmt,884        file_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009885#endif                                 // defined(__APPLE__)|| defined(__FreeBSD__)886 887  std::locale::global(std::locale::classic());888}889 890template <class CharT>891static void test_valid_values_time_zone() {892  using namespace std::literals::chrono_literals;893 894  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");895  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");896 897  const std::locale loc(LOCALE_ja_JP_UTF_8);898  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));899 900  // Non localized output using C-locale901  check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),902        fmt,903        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970904 905  // Use the global locale (fr_FR)906  check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),907        lfmt,908        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970909 910  // Use supplied locale (ja_JP).911  check(loc,912        SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='UTC'\n"),913        lfmt,914        file_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970915 916  std::locale::global(std::locale::classic());917}918 919template <class CharT>920static void test_valid_values() {921  test_valid_values_year<CharT>();922  test_valid_values_month<CharT>();923  test_valid_values_day<CharT>();924  test_valid_values_weekday<CharT>();925  test_valid_values_day_of_year<CharT>();926  test_valid_values_week<CharT>();927  test_valid_values_iso_8601_week<CharT>();928  test_valid_values_date<CharT>();929  test_valid_values_time<CharT>();930  test_valid_values_date_time<CharT>();931  test_valid_values_time_zone<CharT>();932}933 934template <class CharT>935static void test() {936  using namespace std::literals::chrono_literals;937 938  test_no_chrono_specs<CharT>();939  test_valid_values<CharT>();940 941  check_invalid_types<CharT>(942      {SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("c"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("F"),  SV("g"),943       SV("G"),  SV("h"),  SV("H"),  SV("I"),  SV("j"),  SV("m"),  SV("M"),  SV("p"),  SV("r"),  SV("R"),  SV("S"),944       SV("T"),  SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("X"),  SV("y"),  SV("Y"),  SV("z"),945       SV("Z"),  SV("Ec"), SV("EC"), SV("Ex"), SV("EX"), SV("Ey"), SV("EY"), SV("Ez"), SV("Od"), SV("Oe"), SV("OH"),946       SV("OI"), SV("Om"), SV("OM"), SV("OS"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"), SV("Oz")},947      file_seconds(0s));948 949  check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), file_seconds(0s));950  check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), file_seconds(0s));951  check_exception("End of input while parsing a conversion specifier", SV("{:%"), file_seconds(0s));952  check_exception("End of input while parsing the modifier E", SV("{:%E"), file_seconds(0s));953  check_exception("End of input while parsing the modifier O", SV("{:%O"), file_seconds(0s));954 955  // Precision not allowed956  check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), file_seconds(0s));957}958 959int main(int, char**) {960  test<char>();961 962#ifndef TEST_HAS_NO_WIDE_CHARACTERS963  test<wchar_t>();964#endif965 966  return 0;967}968