142 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// class system_Clock;22 23// template<class charT, class traits>24// basic_ostream<charT, traits>&25// operator<<(basic_ostream<charT, traits>& os, const sys_days& dp);26 27#include <cassert>28#include <chrono>29#include <ratio>30#include <sstream>31 32#include "make_string.h"33#include "platform_support.h" // locale name macros34#include "test_macros.h"35#include "assert_macros.h"36#include "concat_macros.h"37 38#define SV(S) MAKE_STRING_VIEW(CharT, S)39 40#define TEST_EQUAL(OUT, EXPECTED) \41 TEST_REQUIRE(OUT == EXPECTED, \42 TEST_WRITE_CONCATENATED( \43 "\nExpression ", #OUT, "\nExpected output ", EXPECTED, "\nActual output ", OUT, '\n'));44 45template <class CharT>46static std::basic_string<CharT> stream_c_locale(const std::chrono::sys_days& dp) {47 std::basic_stringstream<CharT> sstr;48 sstr << dp;49 return sstr.str();50}51 52template <class CharT>53static std::basic_string<CharT> stream_fr_FR_locale(const std::chrono::sys_days& dp) {54 std::basic_stringstream<CharT> sstr;55 const std::locale locale(LOCALE_fr_FR_UTF_8);56 sstr.imbue(locale);57 sstr << dp;58 return sstr.str();59}60 61template <class CharT>62static std::basic_string<CharT> stream_ja_JP_locale(const std::chrono::sys_days& dp) {63 std::basic_stringstream<CharT> sstr;64 const std::locale locale(LOCALE_ja_JP_UTF_8);65 sstr.imbue(locale);66 sstr << dp;67 return sstr.str();68}69 70template <class CharT>71static void test() {72 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{73 std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}}),74 SV("-32768-01-01 is not a valid date"));75 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{76 std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}}),77 SV("1970-01-01"));78 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{79 std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}),80 SV("2000-02-29"));81 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{82 std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}),83 SV("32767-12-31"));84 85 // multiples of days are considered days.86 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}),87 SV("1970-01-22"));88 TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<30 * 86400>>>{89 std::chrono::duration<int, std::ratio<30 * 86400>>{1}}),90 SV("1970-01-31"));91 92 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{93 std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}}),94 SV("-32768-01-01 is not a valid date"));95 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{96 std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}}),97 SV("1970-01-01"));98 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{99 std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}),100 SV("2000-02-29"));101 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{102 std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}),103 SV("32767-12-31"));104 105 // multiples of days are considered days.106 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}),107 SV("1970-01-22"));108 TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<30 * 86400>>>{109 std::chrono::duration<int, std::ratio<30 * 86400>>{1}}),110 SV("1970-01-31"));111 112 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{113 std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}}),114 SV("-32768-01-01 is not a valid date"));115 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{116 std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{1}, std::chrono::day{1}}}),117 SV("1970-01-01"));118 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{119 std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}),120 SV("2000-02-29"));121 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{122 std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}),123 SV("32767-12-31"));124 125 // multiples of days are considered days.126 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}),127 SV("1970-01-22"));128 TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::duration<int, std::ratio<30 * 86400>>>{129 std::chrono::duration<int, std::ratio<30 * 86400>>{1}}),130 SV("1970-01-31"));131}132 133int main(int, char**) {134 test<char>();135 136#ifndef TEST_HAS_NO_WIDE_CHARACTERS137 test<wchar_t>();138#endif139 140 return 0;141}142