brintos

brintos / llvm-project-archived public Read only

0
0
Text · 35.5 KiB · ce3af8e Raw
938 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::day, 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 37template <class CharT>38static void test_no_chrono_specs() {39  using namespace std::literals::chrono_literals;40 41  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));42 43  // Non localized output44 45  // [time.syn]46  //   using nanoseconds  = duration<signed integer type of at least 64 bits, nano>;47  //   using microseconds = duration<signed integer type of at least 55 bits, micro>;48  //   using milliseconds = duration<signed integer type of at least 45 bits, milli>;49  //   using seconds      = duration<signed integer type of at least 35 bits>;50  //   using minutes      = duration<signed integer type of at least 29 bits, ratio<  60>>;51  //   using hours        = duration<signed integer type of at least 23 bits, ratio<3600>>;52  check(53      SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::local_seconds(-17'179'869'184s)); // Minimum value for 35 bits.54  check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::local_seconds(-2'147'483'648s));55 56  check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::local_seconds(-24h));57  check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::local_seconds(-18h));58  check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::local_seconds(-12h));59  check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::local_seconds(-6h));60  check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::local_seconds(-1s));61 62  check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::local_seconds(0s));63  check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::local_seconds(946'684'800s));64  check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::local_seconds(946'688'523s));65 66  check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::local_seconds(2'147'483'647s));67  check(SV("2514-05-30 01:53:03"), SV("{}"), std::chrono::local_seconds(17'179'869'183s)); // Maximum value for 35 bits.68 69  check(SV("2000-01-01 01:02:03.123"), SV("{}"), std::chrono::local_time<std::chrono::milliseconds>(946'688'523'123ms));70 71  std::locale::global(std::locale::classic());72}73 74template <class CharT>75static void test_valid_values_year() {76  using namespace std::literals::chrono_literals;77 78  constexpr std::basic_string_view<CharT> fmt =79      SV("{:%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");80  constexpr std::basic_string_view<CharT> lfmt =81      SV("{:L%%C='%C'%t%%EC='%EC'%t%%y='%y'%t%%Oy='%Oy'%t%%Ey='%Ey'%t%%Y='%Y'%t%%EY='%EY'%n}");82 83  const std::locale loc(LOCALE_ja_JP_UTF_8);84  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));85 86  // Non localized output using C-locale87  check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),88        fmt,89        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 197090 91  check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),92        fmt,93        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 200994 95  // Use the global locale (fr_FR)96  check(SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),97        lfmt,98        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 197099 100  check(SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),101        lfmt,102        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009103 104  // Use supplied locale (ja_JP). This locale has a different alternate.105#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)106  check(loc,107        SV("%C='19'\t%EC='19'\t%y='70'\t%Oy='70'\t%Ey='70'\t%Y='1970'\t%EY='1970'\n"),108        lfmt,109        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970110 111  check(loc,112        SV("%C='20'\t%EC='20'\t%y='09'\t%Oy='09'\t%Ey='09'\t%Y='2009'\t%EY='2009'\n"),113        lfmt,114        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009115#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)116  check(loc,117        SV("%C='19'\t%EC='昭和'\t%y='70'\t%Oy='七十'\t%Ey='45'\t%Y='1970'\t%EY='昭和45年'\n"),118        lfmt,119        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970120 121  check(loc,122        SV("%C='20'\t%EC='平成'\t%y='09'\t%Oy='九'\t%Ey='21'\t%Y='2009'\t%EY='平成21年'\n"),123        lfmt,124        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009125#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__)126 127  std::locale::global(std::locale::classic());128}129 130template <class CharT>131static void test_valid_values_month() {132  using namespace std::literals::chrono_literals;133 134  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");135  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%b='%b'%t%%h='%h'%t%%B='%B'%t%%m='%m'%t%%Om='%Om'%n}");136 137  const std::locale loc(LOCALE_ja_JP_UTF_8);138  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));139 140  // Non localized output using C-locale141  check(SV("%b='Jan'\t%h='Jan'\t%B='January'\t%m='01'\t%Om='01'\n"),142        fmt,143        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970144 145  check(SV("%b='May'\t%h='May'\t%B='May'\t%m='05'\t%Om='05'\n"),146        fmt,147        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033148 149  // Use the global locale (fr_FR)150#if defined(__APPLE__)151  check(SV("%b='jan'\t%h='jan'\t%B='janvier'\t%m='01'\t%Om='01'\n"),152        lfmt,153        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970154#else155  check(SV("%b='janv.'\t%h='janv.'\t%B='janvier'\t%m='01'\t%Om='01'\n"),156        lfmt,157        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970158#endif159 160  check(SV("%b='mai'\t%h='mai'\t%B='mai'\t%m='05'\t%Om='05'\n"),161        lfmt,162        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033163 164  // Use supplied locale (ja_JP). This locale has a different alternate.165#ifdef _WIN32166  check(loc,167        SV("%b='1'\t%h='1'\t%B='1月'\t%m='01'\t%Om='01'\n"),168        lfmt,169        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970170 171  check(loc,172        SV("%b='5'\t%h='5'\t%B='5月'\t%m='05'\t%Om='05'\n"),173        lfmt,174        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033175#elif defined(_AIX)                                  // _WIN32176  check(loc,177        SV("%b='1月'\t%h='1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),178        lfmt,179        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970180 181  check(loc,182        SV("%b='5月'\t%h='5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),183        lfmt,184        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033185#elif defined(__APPLE__)                             // _WIN32186  check(loc,187        SV("%b=' 1'\t%h=' 1'\t%B='1月'\t%m='01'\t%Om='01'\n"),188        lfmt,189        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970190 191  check(loc,192        SV("%b=' 5'\t%h=' 5'\t%B='5月'\t%m='05'\t%Om='05'\n"),193        lfmt,194        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033195#elif defined(__FreeBSD__)                           // _WIN32196  check(loc,197        SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='01'\n"),198        lfmt,199        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970200 201  check(loc,202        SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='05'\n"),203        lfmt,204        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033205#else                                                // _WIN32206  check(loc,207        SV("%b=' 1月'\t%h=' 1月'\t%B='1月'\t%m='01'\t%Om='一'\n"),208        lfmt,209        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970210 211  check(loc,212        SV("%b=' 5月'\t%h=' 5月'\t%B='5月'\t%m='05'\t%Om='五'\n"),213        lfmt,214        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033215#endif                                               // _WIN32216 217  std::locale::global(std::locale::classic());218}219 220template <class CharT>221static void test_valid_values_day() {222  using namespace std::literals::chrono_literals;223 224  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");225  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%d='%d'%t%%Od='%Od'%t%%e='%e'%t%%Oe='%Oe'%n}");226 227  const std::locale loc(LOCALE_ja_JP_UTF_8);228  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));229 230  // Non localized output using C-locale231  check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),232        fmt,233        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970234 235  check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),236        fmt,237        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009238 239  // Use the global locale (fr_FR)240  check(SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),241        lfmt,242        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970243 244  check(SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),245        lfmt,246        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009247 248  // Use supplied locale (ja_JP). This locale has a different alternate.249#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)250  check(loc,251        SV("%d='01'\t%Od='01'\t%e=' 1'\t%Oe=' 1'\n"),252        lfmt,253        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970254 255  check(loc,256        SV("%d='13'\t%Od='13'\t%e='13'\t%Oe='13'\n"),257        lfmt,258        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009259#else // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)260  check(loc,261        SV("%d='01'\t%Od='一'\t%e=' 1'\t%Oe='一'\n"),262        lfmt,263        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970264 265  check(loc,266        SV("%d='13'\t%Od='十三'\t%e='13'\t%Oe='十三'\n"),267        lfmt,268        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009269 270#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)271 272  std::locale::global(std::locale::classic());273}274 275template <class CharT>276static void test_valid_values_weekday() {277  using namespace std::literals::chrono_literals;278 279  constexpr std::basic_string_view<CharT> fmt =280      SV("{:%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");281  constexpr std::basic_string_view<CharT> lfmt =282      SV("{:L%%a='%a'%t%%A='%A'%t%%u='%u'%t%%Ou='%Ou'%t%%w='%w'%t%%Ow='%Ow'%n}");283 284  const std::locale loc(LOCALE_ja_JP_UTF_8);285  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));286 287  // Non localized output using C-locale288  check(SV("%a='Thu'\t%A='Thursday'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),289        fmt,290        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970291 292  check(SV("%a='Sun'\t%A='Sunday'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),293        fmt,294        std::chrono::local_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106295 296  // Use the global locale (fr_FR)297#if defined(__APPLE__)298  check(SV("%a='Jeu'\t%A='Jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),299        lfmt,300        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970301 302  check(SV("%a='Dim'\t%A='Dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),303        lfmt,304        std::chrono::local_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106305#else306  check(SV("%a='jeu.'\t%A='jeudi'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),307        lfmt,308        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970309 310  check(SV("%a='dim.'\t%A='dimanche'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),311        lfmt,312        std::chrono::local_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106313#endif314 315  // Use supplied locale (ja_JP).316  // This locale has a different alternate, but not on all platforms317#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)318  check(loc,319        SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='4'\t%w='4'\t%Ow='4'\n"),320        lfmt,321        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970322 323  check(loc,324        SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='7'\t%w='0'\t%Ow='0'\n"),325        lfmt,326        std::chrono::local_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106327#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)328  check(loc,329        SV("%a='木'\t%A='木曜日'\t%u='4'\t%Ou='四'\t%w='4'\t%Ow='四'\n"),330        lfmt,331        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970332 333  check(loc,334        SV("%a='日'\t%A='日曜日'\t%u='7'\t%Ou='七'\t%w='0'\t%Ow='〇'\n"),335        lfmt,336        std::chrono::local_seconds(4'294'967'295s)); // 06:28:15 UTC on Sunday, 7 February 2106337#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)338 339  std::locale::global(std::locale::classic());340}341 342template <class CharT>343static void test_valid_values_day_of_year() {344  using namespace std::literals::chrono_literals;345 346  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%j='%j'%n}");347  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%j='%j'%n}");348 349  const std::locale loc(LOCALE_ja_JP_UTF_8);350  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));351 352  // Non localized output using C-locale353  check(SV("%j='001'\n"), fmt, std::chrono::local_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970354  check(SV("%j='138'\n"), fmt, std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033355 356  // Use the global locale (fr_FR)357  check(SV("%j='001'\n"), lfmt, std::chrono::local_seconds(0s));             // 00:00:00 UTC Thursday, 1 January 1970358  check(SV("%j='138'\n"), lfmt, std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033359 360  // Use supplied locale (ja_JP). This locale has a different alternate.361  check(loc, SV("%j='001'\n"), lfmt, std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970362 363  check(loc,364        SV("%j='138'\n"),365        lfmt,366        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033367 368  std::locale::global(std::locale::classic());369}370 371template <class CharT>372static void test_valid_values_week() {373  using namespace std::literals::chrono_literals;374 375  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");376  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%U='%U'%t%%OU='%OU'%t%%W='%W'%t%%OW='%OW'%n}");377 378  const std::locale loc(LOCALE_ja_JP_UTF_8);379  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));380 381  // Non localized output using C-locale382  check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),383        fmt,384        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970385 386  check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),387        fmt,388        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033389 390  // Use the global locale (fr_FR)391  check(SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),392        lfmt,393        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970394 395  check(SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),396        lfmt,397        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033398 399  // Use supplied locale (ja_JP). This locale has a different alternate.400#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)401  check(loc,402        SV("%U='00'\t%OU='00'\t%W='00'\t%OW='00'\n"),403        lfmt,404        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970405 406  check(loc,407        SV("%U='20'\t%OU='20'\t%W='20'\t%OW='20'\n"),408        lfmt,409        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033410#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)411  check(loc,412        SV("%U='00'\t%OU='〇'\t%W='00'\t%OW='〇'\n"),413        lfmt,414        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970415 416  check(loc,417        SV("%U='20'\t%OU='二十'\t%W='20'\t%OW='二十'\n"),418        lfmt,419        std::chrono::local_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033420#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)421  std::locale::global(std::locale::classic());422}423 424template <class CharT>425static void test_valid_values_iso_8601_week() {426  using namespace std::literals::chrono_literals;427 428  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");429  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%g='%g'%t%%G='%G'%t%%V='%V'%t%%OV='%OV'%n}");430 431  const std::locale loc(LOCALE_ja_JP_UTF_8);432  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));433 434  // Non localized output using C-locale435  check(SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),436        fmt,437        std::chrono::local_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        std::chrono::local_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"),445        lfmt,446        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970447 448  check(SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),449        lfmt,450        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009451 452  // Use supplied locale (ja_JP). This locale has a different alternate.453#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)454  check(loc,455        SV("%g='70'\t%G='1970'\t%V='01'\t%OV='01'\n"),456        lfmt,457        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970458 459  check(loc,460        SV("%g='09'\t%G='2009'\t%V='07'\t%OV='07'\n"),461        lfmt,462        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009463#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)464  check(loc,465        SV("%g='70'\t%G='1970'\t%V='01'\t%OV='一'\n"),466        lfmt,467        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970468 469  check(loc,470        SV("%g='09'\t%G='2009'\t%V='07'\t%OV='七'\n"),471        lfmt,472        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009473#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)474 475  std::locale::global(std::locale::classic());476}477 478template <class CharT>479static void test_valid_values_date() {480  using namespace std::literals::chrono_literals;481 482  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");483  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%D='%D'%t%%F='%F'%t%%x='%x'%t%%Ex='%Ex'%n}");484 485  const std::locale loc(LOCALE_ja_JP_UTF_8);486  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));487 488  // Non localized output using C-locale489  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/70'\t%Ex='01/01/70'\n"),490        fmt,491        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970492 493  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='02/13/09'\t%Ex='02/13/09'\n"),494        fmt,495        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009496 497  // Use the global locale (fr_FR)498#if defined(__APPLE__) || defined(__FreeBSD__)499  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01.01.1970'\t%Ex='01.01.1970'\n"),500        lfmt,501        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970502 503  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13.02.2009'\t%Ex='13.02.2009'\n"),504        lfmt,505        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009506#else507  check(SV("%D='01/01/70'\t%F='1970-01-01'\t%x='01/01/1970'\t%Ex='01/01/1970'\n"),508        lfmt,509        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970510 511  check(SV("%D='02/13/09'\t%F='2009-02-13'\t%x='13/02/2009'\t%Ex='13/02/2009'\n"),512        lfmt,513        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009514#endif515 516  // Use supplied locale (ja_JP). This locale has a different alternate.517#if defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)518  check(loc,519        SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970/01/01'\t%Ex='1970/01/01'\n"),520        lfmt,521        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970522 523  check(loc,524        SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009/02/13'\t%Ex='2009/02/13'\n"),525        lfmt,526        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009527#else  // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)528  check(loc,529        SV("%D='01/01/70'\t%F='1970-01-01'\t%x='1970年01月01日'\t%Ex='昭和45年01月01日'\n"),530        lfmt,531        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970532 533  check(loc,534        SV("%D='02/13/09'\t%F='2009-02-13'\t%x='2009年02月13日'\t%Ex='平成21年02月13日'\n"),535        lfmt,536        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009537#endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__)538 539  std::locale::global(std::locale::classic());540}541 542template <class CharT>543static void test_valid_values_time() {544  using namespace std::literals::chrono_literals;545 546  constexpr std::basic_string_view<CharT> fmt = SV(547      "{:"548      "%%H='%H'%t"549      "%%OH='%OH'%t"550      "%%I='%I'%t"551      "%%OI='%OI'%t"552      "%%M='%M'%t"553      "%%OM='%OM'%t"554      "%%S='%S'%t"555      "%%OS='%OS'%t"556      "%%p='%p'%t"557      "%%R='%R'%t"558      "%%T='%T'%t"559      "%%r='%r'%t"560      "%%X='%X'%t"561      "%%EX='%EX'%t"562      "%n}");563  constexpr std::basic_string_view<CharT> lfmt = SV(564      "{:L"565      "%%H='%H'%t"566      "%%OH='%OH'%t"567      "%%I='%I'%t"568      "%%OI='%OI'%t"569      "%%M='%M'%t"570      "%%OM='%OM'%t"571      "%%S='%S'%t"572      "%%OS='%OS'%t"573      "%%p='%p'%t"574      "%%R='%R'%t"575      "%%T='%T'%t"576      "%%r='%r'%t"577      "%%X='%X'%t"578      "%%EX='%EX'%t"579      "%n}");580 581  const std::locale loc(LOCALE_ja_JP_UTF_8);582  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));583 584  // Non localized output using C-locale585  check(SV("%H='00'\t"586           "%OH='00'\t"587           "%I='12'\t"588           "%OI='12'\t"589           "%M='00'\t"590           "%OM='00'\t"591           "%S='00'\t"592           "%OS='00'\t"593           "%p='AM'\t"594           "%R='00:00'\t"595           "%T='00:00:00'\t"596           "%r='12:00:00 AM'\t"597           "%X='00:00:00'\t"598           "%EX='00:00:00'\t"599           "\n"),600        fmt,601        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970602 603  check(SV("%H='23'\t"604           "%OH='23'\t"605           "%I='11'\t"606           "%OI='11'\t"607           "%M='31'\t"608           "%OM='31'\t"609           "%S='30.123'\t"610           "%OS='30.123'\t"611           "%p='PM'\t"612           "%R='23:31'\t"613           "%T='23:31:30.123'\t"614           "%r='11:31:30 PM'\t"615           "%X='23:31:30'\t"616           "%EX='23:31:30'\t"617           "\n"),618        fmt,619        std::chrono::local_time<std::chrono::milliseconds>(620            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009621  // Use the global locale (fr_FR)622  check(SV("%H='00'\t"623           "%OH='00'\t"624           "%I='12'\t"625           "%OI='12'\t"626           "%M='00'\t"627           "%OM='00'\t"628           "%S='00'\t"629           "%OS='00'\t"630#if defined(_AIX)631           "%p='AM'\t"632#else633           "%p=''\t"634#endif635           "%R='00:00'\t"636           "%T='00:00:00'\t"637#ifdef _WIN32638           "%r='00:00:00'\t"639#elif defined(_AIX)640           "%r='12:00:00 AM'\t"641#elif defined(__APPLE__) || defined(__FreeBSD__)642           "%r=''\t"643#else644           "%r='12:00:00 '\t"645#endif646           "%X='00:00:00'\t"647           "%EX='00:00:00'\t"648           "\n"),649        lfmt,650        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970651 652  check(SV("%H='23'\t"653           "%OH='23'\t"654           "%I='11'\t"655           "%OI='11'\t"656           "%M='31'\t"657           "%OM='31'\t"658           "%S='30,123'\t"659           "%OS='30,123'\t"660#if defined(_AIX)661           "%p='PM'\t"662#else663           "%p=''\t"664#endif665           "%R='23:31'\t"666           "%T='23:31:30,123'\t"667#ifdef _WIN32668           "%r='23:31:30'\t"669#elif defined(_AIX)670           "%r='11:31:30 PM'\t"671#elif defined(__APPLE__) || defined(__FreeBSD__)672           "%r=''\t"673#else674           "%r='11:31:30 '\t"675#endif676           "%X='23:31:30'\t"677           "%EX='23:31:30'\t"678           "\n"),679        lfmt,680        std::chrono::local_time<std::chrono::milliseconds>(681            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009682 683  // Use supplied locale (ja_JP). This locale has a different alternate.a684#if defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)685  check(loc,686        SV("%H='00'\t"687           "%OH='00'\t"688           "%I='12'\t"689           "%OI='12'\t"690           "%M='00'\t"691           "%OM='00'\t"692           "%S='00'\t"693           "%OS='00'\t"694           "%p='午前'\t"695           "%R='00:00'\t"696           "%T='00:00:00'\t"697#  if defined(__APPLE__) || defined(__FreeBSD__)698           "%r='12:00:00 午前'\t"699           "%X='00時00分00秒'\t"700           "%EX='00時00分00秒'\t"701#  elif defined(_WIN32)702           "%r='0:00:00'\t"703           "%X='0:00:00'\t"704           "%EX='0:00:00'\t"705#  else706           "%r='午前12:00:00'\t"707           "%X='00:00:00'\t"708           "%EX='00:00:00'\t"709#  endif710           "\n"),711        lfmt,712        std::chrono::hh_mm_ss(0s));713 714  check(loc,715        SV("%H='23'\t"716           "%OH='23'\t"717           "%I='11'\t"718           "%OI='11'\t"719           "%M='31'\t"720           "%OM='31'\t"721           "%S='30.123'\t"722           "%OS='30.123'\t"723           "%p='午後'\t"724           "%R='23:31'\t"725           "%T='23:31:30.123'\t"726#  if defined(__APPLE__) || defined(__FreeBSD__)727           "%r='11:31:30 午後'\t"728           "%X='23時31分30秒'\t"729           "%EX='23時31分30秒'\t"730#  elif defined(_WIN32)731           "%r='23:31:30'\t"732           "%X='23:31:30'\t"733           "%EX='23:31:30'\t"734#  else735           "%r='午後11:31:30'\t"736           "%X='23:31:30'\t"737           "%EX='23:31:30'\t"738#  endif739           "\n"),740        lfmt,741        std::chrono::hh_mm_ss(23h + 31min + 30s + 123ms));742#else  // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)743  check(loc,744        SV("%H='00'\t"745           "%OH='〇'\t"746           "%I='12'\t"747           "%OI='十二'\t"748           "%M='00'\t"749           "%OM='〇'\t"750           "%S='00'\t"751           "%OS='〇'\t"752           "%p='午前'\t"753           "%R='00:00'\t"754           "%T='00:00:00'\t"755           "%r='午前12時00分00秒'\t"756           "%X='00時00分00秒'\t"757           "%EX='00時00分00秒'\t"758           "\n"),759        lfmt,760        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970761 762  check(loc,763        SV("%H='23'\t"764           "%OH='二十三'\t"765           "%I='11'\t"766           "%OI='十一'\t"767           "%M='31'\t"768           "%OM='三十一'\t"769           "%S='30.123'\t"770           "%OS='三十.123'\t"771           "%p='午後'\t"772           "%R='23:31'\t"773           "%T='23:31:30.123'\t"774           "%r='午後11時31分30秒'\t"775           "%X='23時31分30秒'\t"776           "%EX='23時31分30秒'\t"777           "\n"),778        lfmt,779        std::chrono::local_time<std::chrono::milliseconds>(780            1'234'567'890'123ms)); // 23:31:30 UTC on Friday, 13 February 2009781#endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__)782 783  std::locale::global(std::locale::classic());784}785 786template <class CharT>787static void test_valid_values_date_time() {788  using namespace std::literals::chrono_literals;789 790  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%c='%c'%t%%Ec='%Ec'%n}");791  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%c='%c'%t%%Ec='%Ec'%n}");792 793  const std::locale loc(LOCALE_ja_JP_UTF_8);794  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));795 796  // Non localized output using C-locale797  check(SV("%c='Thu Jan  1 00:00:00 1970'\t%Ec='Thu Jan  1 00:00:00 1970'\n"),798        fmt,799        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970800 801  check(SV("%c='Fri Feb 13 23:31:30 2009'\t%Ec='Fri Feb 13 23:31:30 2009'\n"),802        fmt,803        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009804 805  // Use the global locale (fr_FR)806  check(807// https://sourceware.org/bugzilla/show_bug.cgi?id=24054808#if defined(__powerpc__) && defined(__linux__)809      SV("%c='jeu. 01 janv. 1970 00:00:00 UTC'\t%Ec='jeu. 01 janv. 1970 00:00:00 UTC'\n"),810#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29811      SV("%c='jeu. 01 janv. 1970 00:00:00 GMT'\t%Ec='jeu. 01 janv. 1970 00:00:00 GMT'\n"),812#elif defined(_AIX)813      SV("%c=' 1 janvier 1970 à 00:00:00 UTC'\t%Ec=' 1 janvier 1970 à 00:00:00 UTC'\n"),814#elif defined(__APPLE__)815      SV("%c='Jeu  1 jan 00:00:00 1970'\t%Ec='Jeu  1 jan 00:00:00 1970'\n"),816#elif defined(_WIN32)817      SV("%c='01/01/1970 00:00:00'\t%Ec='01/01/1970 00:00:00'\n"),818#elif defined(__FreeBSD__)819      SV("%c='jeu.  1 janv. 00:00:00 1970'\t%Ec='jeu.  1 janv. 00:00:00 1970'\n"),820#else821      SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"),822#endif823      lfmt,824      std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970825 826  check(827// https://sourceware.org/bugzilla/show_bug.cgi?id=24054828#if defined(__powerpc__) && defined(__linux__)829      SV("%c='ven. 13 févr. 2009 23:31:30 UTC'\t%Ec='ven. 13 févr. 2009 23:31:30 UTC'\n"),830#elif defined(__GLIBC__) && __GLIBC__ <= 2 && __GLIBC_MINOR__ < 29831      SV("%c='ven. 13 févr. 2009 23:31:30 GMT'\t%Ec='ven. 13 févr. 2009 23:31:30 GMT'\n"),832#elif defined(_AIX)833      SV("%c='13 février 2009 à 23:31:30 UTC'\t%Ec='13 février 2009 à 23:31:30 UTC'\n"),834#elif defined(__APPLE__)835      SV("%c='Ven 13 fév 23:31:30 2009'\t%Ec='Ven 13 fév 23:31:30 2009'\n"),836#elif defined(_WIN32)837      SV("%c='13/02/2009 23:31:30'\t%Ec='13/02/2009 23:31:30'\n"),838#elif defined(__FreeBSD__)839      SV("%c='ven. 13 févr. 23:31:30 2009'\t%Ec='ven. 13 févr. 23:31:30 2009'\n"),840#else841      SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"),842#endif843      lfmt,844      std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009845 846  // Use supplied locale (ja_JP). This locale has a different alternate.a847#if defined(__APPLE__) || defined(__FreeBSD__)848  check(loc,849        SV("%c='木  1/ 1 00:00:00 1970'\t%Ec='木  1/ 1 00:00:00 1970'\n"),850        lfmt,851        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970852  check(loc,853        SV("%c='金  2/13 23:31:30 2009'\t%Ec='金  2/13 23:31:30 2009'\n"),854        lfmt,855        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009856#elif defined(_AIX)                                  // defined(__APPLE__)|| defined(__FreeBSD__)857  check(loc,858        SV("%c='1970年01月 1日 00:00:00 UTC'\t%Ec='1970年01月 1日 00:00:00 UTC'\n"),859        lfmt,860        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970861  check(loc,862        SV("%c='2009年02月13日 23:31:30 UTC'\t%Ec='2009年02月13日 23:31:30 UTC'\n"),863        lfmt,864        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009865#elif defined(_WIN32)                                // defined(__APPLE__)|| defined(__FreeBSD__)866  check(loc,867        SV("%c='1970/01/01 0:00:00'\t%Ec='1970/01/01 0:00:00'\n"),868        lfmt,869        std::chrono::sys_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970870  check(loc,871        SV("%c='2009/02/13 23:31:30'\t%Ec='2009/02/13 23:31:30'\n"),872        lfmt,873        std::chrono::sys_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009874#else                                                // defined(__APPLE__)|| defined(__FreeBSD__)875  check(loc,876        SV("%c='1970年01月01日 00時00分00秒'\t%Ec='昭和45年01月01日 00時00分00秒'\n"),877        lfmt,878        std::chrono::local_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970879 880  check(loc,881        SV("%c='2009年02月13日 23時31分30秒'\t%Ec='平成21年02月13日 23時31分30秒'\n"),882        lfmt,883        std::chrono::local_seconds(1'234'567'890s)); // 23:31:30 UTC on Friday, 13 February 2009884#endif                                               // defined(__APPLE__)|| defined(__FreeBSD__)885 886  std::locale::global(std::locale::classic());887}888 889template <class CharT>890static void test_valid_values() {891  test_valid_values_year<CharT>();892  test_valid_values_month<CharT>();893  test_valid_values_day<CharT>();894  test_valid_values_weekday<CharT>();895  test_valid_values_day_of_year<CharT>();896  test_valid_values_week<CharT>();897  test_valid_values_iso_8601_week<CharT>();898  test_valid_values_date<CharT>();899  test_valid_values_time<CharT>();900  test_valid_values_date_time<CharT>();901}902 903template <class CharT>904static void test() {905  using namespace std::literals::chrono_literals;906 907  test_no_chrono_specs<CharT>();908  test_valid_values<CharT>();909  check_invalid_types<CharT>(910      {911          SV("a"),  SV("A"),  SV("b"),  SV("B"),  SV("c"),  SV("C"),  SV("d"),  SV("D"),  SV("e"),  SV("F"),  SV("g"),912          SV("G"),  SV("h"),  SV("H"),  SV("I"),  SV("j"),  SV("m"),  SV("M"),  SV("p"),  SV("r"),  SV("R"),  SV("S"),913          SV("T"),  SV("u"),  SV("U"),  SV("V"),  SV("w"),  SV("W"),  SV("x"),  SV("X"),  SV("y"),  SV("Y"),  SV("Ec"),914          SV("EC"), SV("Ex"), SV("EX"), SV("Ey"), SV("EY"), SV("Od"), SV("Oe"), SV("OH"), SV("OI"), SV("Om"), SV("OM"),915          SV("OS"), SV("Ou"), SV("OU"), SV("OV"), SV("Ow"), SV("OW"), SV("Oy"),916      },917      std::chrono::local_seconds(0s));918 919  check_exception("The format specifier expects a '%' or a '}'", SV("{:A"), std::chrono::local_seconds(0s));920  check_exception("The chrono specifiers contain a '{'", SV("{:%%{"), std::chrono::local_seconds(0s));921  check_exception("End of input while parsing a conversion specifier", SV("{:%"), std::chrono::local_seconds(0s));922  check_exception("End of input while parsing the modifier E", SV("{:%E"), std::chrono::local_seconds(0s));923  check_exception("End of input while parsing the modifier O", SV("{:%O"), std::chrono::local_seconds(0s));924 925  // Precision not allowed926  check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::local_seconds(0s));927}928 929int main(int, char**) {930  test<char>();931 932#ifndef TEST_HAS_NO_WIDE_CHARACTERS933  test<wchar_t>();934#endif935 936  return 0;937}938