https://github.com/mordante created https://github.com/llvm/llvm-project/pull/86127
The formatting of years has been done manually since the results of %Y outside the "typical" range may produce unexpected values. The same applies to %F which is identical to %Y-%m-%d. Note of these conversion specifiers is affected by the locale used. So it's trivial to manually handle this case. This removes several platform specific ifdefs from the tests. >From 0aeab5a82110d6e3d01fb8c8562f5569c84203a3 Mon Sep 17 00:00:00 2001 From: Mark de Wever <ko...@xs4all.nl> Date: Thu, 21 Mar 2024 15:22:13 +0100 Subject: [PATCH] [libc++][chrono] Improves date formatting. The formatting of years has been done manually since the results of %Y outside the "typical" range may produce unexpected values. The same applies to %F which is identical to %Y-%m-%d. Note of these conversion specifiers is affected by the locale used. So it's trivial to manually handle this case. This removes several platform specific ifdefs from the tests. --- libcxx/include/__chrono/formatter.h | 16 +++++----- .../time.cal.ymd.nonmembers/ostream.pass.cpp | 31 ------------------- .../sys_date.ostream.pass.cpp | 31 ------------------- .../formatter.year_month_day.pass.cpp | 24 -------------- 4 files changed, 7 insertions(+), 95 deletions(-) diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h index 8b8592041a1fb9..217979e88c93db 100644 --- a/libcxx/include/__chrono/formatter.h +++ b/libcxx/include/__chrono/formatter.h @@ -322,15 +322,13 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( __formatter::__format_year(__sstr, __t.tm_year + 1900); break; - case _CharT('F'): { - int __year = __t.tm_year + 1900; - if (__year < 1000) { - __formatter::__format_year(__sstr, __year); - __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); - } else - __facet.put( - {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); - } break; + case _CharT('F'): + // Depending on the platform's libc the range of supported years is + // limited. Intead of of testing all conditions use the internal + // implementation unconditionally. + __formatter::__format_year(__sstr, __t.tm_year + 1900); + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); + break; case _CharT('z'): __formatter::__format_zone_offset(__sstr, __z.__offset, false); diff --git a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp index ffc737fcad5dd2..3a37e75bbcd2e4 100644 --- a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp +++ b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp @@ -89,20 +89,9 @@ static void test() { TEST_EQUAL(stream_c_locale<CharT>( std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}), SV("2000-02-29")); - -#if defined(_AIX) - TEST_EQUAL(stream_c_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_c_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_c_locale<CharT>( std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), SV("32767-12-31")); -#endif // defined(_AIX) TEST_EQUAL(stream_fr_FR_locale<CharT>( std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}), @@ -122,19 +111,9 @@ static void test() { TEST_EQUAL(stream_fr_FR_locale<CharT>( std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}), SV("2000-02-29")); -#if defined(_AIX) - TEST_EQUAL(stream_fr_FR_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_fr_FR_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_fr_FR_locale<CharT>( std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), SV("32767-12-31")); -#endif // defined(_AIX) TEST_EQUAL(stream_ja_JP_locale<CharT>( std::chrono::year_month_day{std::chrono::year{-32'768}, std::chrono::month{1}, std::chrono::day{1}}), @@ -154,19 +133,9 @@ static void test() { TEST_EQUAL(stream_ja_JP_locale<CharT>( std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}), SV("2000-02-29")); -#if defined(_AIX) - TEST_EQUAL(stream_ja_JP_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_ja_JP_locale<CharT>( - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_ja_JP_locale<CharT>( std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}), SV("32767-12-31")); -#endif // defined(_AIX) } int main(int, char**) { diff --git a/libcxx/test/std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp index 7af3ebf7768072..1523b993555478 100644 --- a/libcxx/test/std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp +++ b/libcxx/test/std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp @@ -81,20 +81,9 @@ static void test() { TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}), SV("2000-02-29")); - -#if defined(_AIX) - TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), SV("32767-12-31")); -#endif // defined(_AIX) // multiples of days are considered days. TEST_EQUAL(stream_c_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}), @@ -112,19 +101,9 @@ static void test() { TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}), SV("2000-02-29")); -#if defined(_AIX) - TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), SV("32767-12-31")); -#endif // defined(_AIX) // multiples of days are considered days. TEST_EQUAL(stream_fr_FR_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}), @@ -142,19 +121,9 @@ static void test() { TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{2000}, std::chrono::month{2}, std::chrono::day{29}}}), SV("2000-02-29")); -#if defined(_AIX) - TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("+32767-12-31")); -#elif defined(_WIN32) // defined(_AIX) - TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{ - std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), - SV("")); -#else // defined(_AIX) TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_days{ std::chrono::year_month_day{std::chrono::year{32'767}, std::chrono::month{12}, std::chrono::day{31}}}), SV("32767-12-31")); -#endif // defined(_AIX) // multiples of days are considered days. TEST_EQUAL(stream_ja_JP_locale<CharT>(std::chrono::sys_time<std::chrono::weeks>{std::chrono::weeks{3}}), diff --git a/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp b/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp index 5a2b7afa37a865..1f2af1cb0530de 100644 --- a/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp +++ b/libcxx/test/std/time/time.syn/formatter.year_month_day.pass.cpp @@ -62,17 +62,6 @@ static void test_no_chrono_specs() { std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{2}, std::chrono::day{31}}); // Valid year, invalid month, valid day -#ifdef _WIN32 - check(SV(" is not a valid date"), - SV("{}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}}); - check(SV("****** is not a valid date******"), - SV("{:*^32}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}}); - check(SV("*********** is not a valid date"), - SV("{:*>31}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}}); -#else // _WIN32 check(SV("1970-00-31 is not a valid date"), SV("{}"), std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}}); @@ -82,20 +71,8 @@ static void test_no_chrono_specs() { check(SV("*1970-00-31 is not a valid date"), SV("{:*>31}"), std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{31}}); -#endif // _WIN32 // Valid year, invalid month, invalid day -#ifdef _WIN32 - check(SV(" is not a valid date"), - SV("{}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}}); - check(SV("****** is not a valid date******"), - SV("{:*^32}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}}); - check(SV("*********** is not a valid date"), - SV("{:*>31}"), - std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}}); -#else // _WIN32 check(SV("1970-00-32 is not a valid date"), SV("{}"), std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}}); @@ -105,7 +82,6 @@ static void test_no_chrono_specs() { check(SV("*1970-00-32 is not a valid date"), SV("{:*>31}"), std::chrono::year_month_day{std::chrono::year{1970}, std::chrono::month{0}, std::chrono::day{32}}); -#endif // _WIN32 // Invalid year, valid month, valid day check(SV("-32768-01-31 is not a valid date"), _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits