16f7976c8SMark de Wever //===----------------------------------------------------------------------===// 2*6a54dfbfSLouis Dionne // 36f7976c8SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46f7976c8SMark de Wever // See https://llvm.org/LICENSE.txt for license information. 56f7976c8SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66f7976c8SMark de Wever // 76f7976c8SMark de Wever //===----------------------------------------------------------------------===// 86f7976c8SMark de Wever 96f7976c8SMark de Wever // UNSUPPORTED: c++03, c++11, c++14, c++17 106f7976c8SMark de Wever // UNSUPPORTED: no-localization 116f7976c8SMark de Wever 126f7976c8SMark de Wever // TODO FMT This test should not require std::to_chars(floating-point) 136f7976c8SMark de Wever // XFAIL: availability-fp_to_chars-missing 146f7976c8SMark de Wever 15a4422a51SMark de Wever // XFAIL: libcpp-has-no-experimental-tzdb 166f7976c8SMark de Wever 176f7976c8SMark de Wever // REQUIRES: locale.fr_FR.UTF-8 186f7976c8SMark de Wever // REQUIRES: locale.ja_JP.UTF-8 196f7976c8SMark de Wever 206f7976c8SMark de Wever // <chrono> 216f7976c8SMark de Wever // 226f7976c8SMark de Wever // template<class charT> struct formatter<chrono::sys_info, charT>; 236f7976c8SMark de Wever 246f7976c8SMark de Wever #include <chrono> 256f7976c8SMark de Wever #include <format> 266f7976c8SMark de Wever 276f7976c8SMark de Wever #include <cassert> 286f7976c8SMark de Wever #include <concepts> 296f7976c8SMark de Wever #include <locale> 306f7976c8SMark de Wever #include <iostream> 316f7976c8SMark de Wever #include <type_traits> 326f7976c8SMark de Wever 336f7976c8SMark de Wever #include "formatter_tests.h" 346f7976c8SMark de Wever #include "make_string.h" 356f7976c8SMark de Wever #include "platform_support.h" // locale name macros 366f7976c8SMark de Wever #include "test_macros.h" 376f7976c8SMark de Wever 386f7976c8SMark de Wever template <class CharT> 396f7976c8SMark de Wever static void test_no_chrono_specs() { 406f7976c8SMark de Wever // This test libc++ specific due to 416f7976c8SMark de Wever // [time.zone.info.sys]/7 426f7976c8SMark de Wever // Effects: Streams out the sys_info object r in an unspecified format. 436f7976c8SMark de Wever #ifdef _LIBCPP_VERSION 446f7976c8SMark de Wever using namespace std::literals::chrono_literals; 456f7976c8SMark de Wever namespace tz = std::chrono; 466f7976c8SMark de Wever 476f7976c8SMark de Wever std::locale::global(std::locale(LOCALE_fr_FR_UTF_8)); 486f7976c8SMark de Wever 496f7976c8SMark de Wever // Non localized output 506f7976c8SMark de Wever 516f7976c8SMark de Wever check(SV("[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min \"TZ\""), 526f7976c8SMark de Wever SV("{}"), 536f7976c8SMark de Wever tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"}); 546f7976c8SMark de Wever 556f7976c8SMark de Wever check(SV("[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min \"DMY\""), 566f7976c8SMark de Wever SV("{}"), 576f7976c8SMark de Wever tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}), 586f7976c8SMark de Wever static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}), 596f7976c8SMark de Wever 12h + 23min + 45s, 606f7976c8SMark de Wever -67min, 616f7976c8SMark de Wever "DMY"}); 626f7976c8SMark de Wever 636f7976c8SMark de Wever std::locale::global(std::locale::classic()); 646f7976c8SMark de Wever #endif // _LIBCPP_VERSION 656f7976c8SMark de Wever } 666f7976c8SMark de Wever 676f7976c8SMark de Wever template <class CharT> 686f7976c8SMark de Wever static void test_valid_values() { 696f7976c8SMark de Wever using namespace std::literals::chrono_literals; 706f7976c8SMark de Wever 716f7976c8SMark de Wever constexpr std::basic_string_view<CharT> fmt = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}"); 726f7976c8SMark de Wever constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}"); 736f7976c8SMark de Wever 746f7976c8SMark de Wever const std::locale loc(LOCALE_ja_JP_UTF_8); 756f7976c8SMark de Wever std::locale::global(std::locale(LOCALE_fr_FR_UTF_8)); 766f7976c8SMark de Wever 776f7976c8SMark de Wever // Non localized output using C-locale 786f7976c8SMark de Wever check(SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"), 796f7976c8SMark de Wever fmt, 806f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"}); 816f7976c8SMark de Wever 826f7976c8SMark de Wever check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"), 836f7976c8SMark de Wever fmt, 846f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"}); 856f7976c8SMark de Wever 866f7976c8SMark de Wever check(SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"), 876f7976c8SMark de Wever fmt, 886f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"}); 896f7976c8SMark de Wever 906f7976c8SMark de Wever // Use the global locale (fr_FR) 916f7976c8SMark de Wever check(SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"), 926f7976c8SMark de Wever lfmt, 936f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"}); 946f7976c8SMark de Wever 956f7976c8SMark de Wever check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"), 966f7976c8SMark de Wever lfmt, 976f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"}); 986f7976c8SMark de Wever 996f7976c8SMark de Wever check(SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"), 1006f7976c8SMark de Wever lfmt, 1016f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"}); 1026f7976c8SMark de Wever 1036f7976c8SMark de Wever // Use supplied locale (ja_JP). 1046f7976c8SMark de Wever check(loc, 1056f7976c8SMark de Wever SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"), 1066f7976c8SMark de Wever lfmt, 1076f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"}); 1086f7976c8SMark de Wever 1096f7976c8SMark de Wever check(loc, 1106f7976c8SMark de Wever SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"), 1116f7976c8SMark de Wever lfmt, 1126f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"}); 1136f7976c8SMark de Wever 1146f7976c8SMark de Wever check(loc, 1156f7976c8SMark de Wever SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"), 1166f7976c8SMark de Wever lfmt, 1176f7976c8SMark de Wever std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"}); 1186f7976c8SMark de Wever 1196f7976c8SMark de Wever std::locale::global(std::locale::classic()); 1206f7976c8SMark de Wever } 1216f7976c8SMark de Wever 1226f7976c8SMark de Wever template <class CharT> 1236f7976c8SMark de Wever static void test() { 1246f7976c8SMark de Wever test_no_chrono_specs<CharT>(); 1256f7976c8SMark de Wever test_valid_values<CharT>(); 1266f7976c8SMark de Wever 1276f7976c8SMark de Wever check_invalid_types<CharT>({SV("z"), SV("Z"), SV("Ez"), SV("Oz")}, std::chrono::sys_info{}); 1286f7976c8SMark de Wever } 1296f7976c8SMark de Wever 1306f7976c8SMark de Wever int main(int, char**) { 1316f7976c8SMark de Wever test<char>(); 1326f7976c8SMark de Wever 1336f7976c8SMark de Wever #ifndef TEST_HAS_NO_WIDE_CHARACTERS 1346f7976c8SMark de Wever test<wchar_t>(); 1356f7976c8SMark de Wever #endif 1366f7976c8SMark de Wever 1376f7976c8SMark de Wever return 0; 1386f7976c8SMark de Wever } 139