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-exception 5 // 6 //===----------------------------------------------------------------------===// 7 8 // UNSUPPORTED: c++03, c++11, c++14, c++17 9 // UNSUPPORTED: no-filesystem, no-localization, no-tzdb 10 // UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME 11 12 // TODO FMT This test should not require std::to_chars(floating-point) 13 // XFAIL: availability-fp_to_chars-missing 14 15 // XFAIL: libcpp-has-no-experimental-tzdb 16 // XFAIL: availability-tzdb-missing 17 18 // REQUIRES: locale.fr_FR.UTF-8 19 // REQUIRES: locale.ja_JP.UTF-8 20 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 macros 38 #include "test_macros.h" 39 40 template <class CharT> 41 static 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 output 47 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 80 template <class CharT> 81 static 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-locale 93 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 1970 96 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 2009 100 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 1970 105 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 2009 109 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 1970 116 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 2009 121 #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 1970 126 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 2009 131 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX)||defined(__FreeBSD__) 132 133 std::locale::global(std::locale::classic()); 134 } 135 136 template <class CharT> 137 static 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-locale 147 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 1970 150 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 2033 154 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 1970 160 #else 161 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 1970 164 #endif 165 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 2033 169 170 // Use supplied locale (ja_JP). This locale has a different alternate. 171 #ifdef _WIN32 172 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 1970 176 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 2033 181 #elif defined(_AIX) // _WIN32 182 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 1970 186 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 2033 191 #elif defined(__APPLE__) // _WIN32 192 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 1970 196 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 2033 201 #elif defined(__FreeBSD__) // _WIN32 202 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 1970 206 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 2033 211 #else // _WIN32 212 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 1970 216 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 2033 221 #endif // _WIN32 222 223 std::locale::global(std::locale::classic()); 224 } 225 226 template <class CharT> 227 static 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-locale 237 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 1970 240 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 2009 244 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 1970 249 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 2009 253 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 1970 260 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 2009 265 #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 1970 270 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 2009 275 276 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 277 278 std::locale::global(std::locale::classic()); 279 } 280 281 template <class CharT> 282 static 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-locale 294 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 1970 297 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 2106 301 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 1970 307 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 2106 311 #else 312 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 1970 315 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 2106 319 #endif 320 321 // Use supplied locale (ja_JP). 322 // This locale has a different alternate, but not on all platforms 323 #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 1970 328 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 2106 333 #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 1970 338 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 2106 343 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 344 345 std::locale::global(std::locale::classic()); 346 } 347 348 template <class CharT> 349 static 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-locale 359 check(SV("%j='001'\n"), fmt, std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970 360 check(SV("%j='138'\n"), fmt, std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033 361 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 1970 364 check(SV("%j='138'\n"), lfmt, std::chrono::utc_seconds(2'000'000'000s)); // 03:33:20 UTC on Wednesday, 18 May 2033 365 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 1970 368 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 2033 371 372 std::locale::global(std::locale::classic()); 373 } 374 375 template <class CharT> 376 static 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-locale 386 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 1970 389 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 2033 393 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 1970 398 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 2033 402 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 1970 409 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 2033 414 #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 1970 419 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 2033 424 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 425 std::locale::global(std::locale::classic()); 426 } 427 428 template <class CharT> 429 static 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-locale 439 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 1970 442 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 2009 446 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 1970 451 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 2009 455 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 1970 462 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 2009 467 #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 1970 472 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 2009 477 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 478 479 std::locale::global(std::locale::classic()); 480 } 481 482 template <class CharT> 483 static 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-locale 493 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 1970 496 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 2009 500 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 1970 506 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 2009 510 #else 511 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 1970 514 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 2009 518 #endif 519 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 1970 526 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 2009 531 #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 1970 536 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 2009 541 #endif // defined(_WIN32) || defined(__APPLE__) || defined(_AIX) || defined(__FreeBSD__) 542 543 std::locale::global(std::locale::classic()); 544 } 545 546 template <class CharT> 547 static 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-locale 589 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 1970 606 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 2009 625 // 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 #else 637 "%p=''\t" 638 #endif 639 "%R='00:00'\t" 640 "%T='00:00:00'\t" 641 #ifdef _WIN32 642 "%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 #else 648 "%r='12:00:00 '\t" 649 #endif 650 "%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 1970 655 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 #else 667 "%p=''\t" 668 #endif 669 "%R='23:31'\t" 670 "%T='23:31:30,123'\t" 671 #ifdef _WIN32 672 "%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 #else 678 "%r='11:31:30 '\t" 679 #endif 680 "%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 2009 686 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 # else 701 "%p='午前'\t" 702 # endif 703 "%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 # else 709 "%r='12:00:00 午前'\t" 710 # endif 711 "%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 # else 718 "%r='午前12:00:00'\t" 719 "%X='00:00:00'\t" 720 "%EX='00:00:00'\t" 721 # endif 722 "\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 # else 738 "%p='午後'\t" 739 # endif 740 "%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 # else 746 "%r='11:31:30 午後'\t" 747 # endif 748 "%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 # else 755 "%r='午後11:31:30'\t" 756 "%X='23:31:30'\t" 757 "%EX='23:31:30'\t" 758 # endif 759 "\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 1970 781 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 2009 801 #endif // defined(__APPLE__) || defined(_AIX) || defined(_WIN32) || defined(__FreeBSD__) 802 803 std::locale::global(std::locale::classic()); 804 } 805 806 template <class CharT> 807 static 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-locale 817 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 1970 820 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 2009 824 825 // Use the global locale (fr_FR) 826 check( 827 // https://sourceware.org/bugzilla/show_bug.cgi?id=24054 828 #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__ < 29 831 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 #else 841 SV("%c='jeu. 01 janv. 1970 00:00:00'\t%Ec='jeu. 01 janv. 1970 00:00:00'\n"), 842 #endif 843 lfmt, 844 std::chrono::utc_seconds(0s)); // 00:00:00 UTC Thursday, 1 January 1970 845 846 check( 847 // https://sourceware.org/bugzilla/show_bug.cgi?id=24054 848 #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__ < 29 851 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 #else 861 SV("%c='ven. 13 févr. 2009 23:31:30'\t%Ec='ven. 13 févr. 2009 23:31:30'\n"), 862 #endif 863 lfmt, 864 std::chrono::utc_seconds(1'234'567'890s + 24s)); // 23:31:30 UTC on Friday, 13 February 2009 865 866 // Use supplied locale (ja_JP). This locale has a different alternate.a 867 #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 1970 872 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 2009 876 #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 1970 881 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 2009 885 #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 1970 890 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 2009 894 #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 1970 899 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 2009 904 #endif // defined(__APPLE__)|| defined(__FreeBSD__) 905 906 std::locale::global(std::locale::classic()); 907 } 908 909 template <class CharT> 910 static 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-locale 920 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 1970 923 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 1970 928 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 1970 934 935 std::locale::global(std::locale::classic()); 936 } 937 938 template <class CharT> 939 static 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 952 template <class CharT> 953 static 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 be 970 // included in the UTC time. The number of leap seconds for times far in the 971 // future are not yet known and may change in the future. 972 template <class CharT> 973 static 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 allowed 993 check_exception("The format specifier expects a '%' or a '}'", SV("{:.3}"), std::chrono::utc_seconds(0s)); 994 } 995 996 int main(int, char**) { 997 test<char>(); 998 999 #ifndef TEST_HAS_NO_WIDE_CHARACTERS 1000 test<wchar_t>(); 1001 #endif 1002 1003 return 0; 1004 } 1005