On Wed, Jun 4, 2025 at 1:08 PM Tomasz Kamiński <tkami...@redhat.com> wrote:

> Adding a tests for behavior of the ostream operator and the formatting
> with empty chronio-spec for the chrono types. Current coverage is:
>
This should say "chron-spec", consider it to be fixed locally.

>  * time point, zoned_time and local_time_format in this commit,
>  * duration and hh_mm_ss in r16-1099-gac0a04b7a254fb,
>  * calendar types in r16-1016-g28a17985dd34b7.
>
> libstdc++-v3/ChangeLog:
>
>         * testsuite/std/time/format/empty_spec.cc: New tests.
> ---
> The only change is mention of the duration test in commit message,
> after the rebase. OK for trunk?
>
>  .../testsuite/std/time/format/empty_spec.cc   | 208 ++++++++++++++++--
>  1 file changed, 194 insertions(+), 14 deletions(-)
>
> diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> index 46942dc30fc..1cb0066a608 100644
> --- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> +++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc
> @@ -12,6 +12,46 @@ using namespace std::chrono;
>  #define WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S)
>  #define WIDEN(S) WIDEN_(_CharT, S)
>
> +template<typename CharT, typename T>
> +void
> +test_no_empty_spec()
> +{
> +  try
> +  {
> +    T t{};
> +
> +    if constexpr (std::is_same_v<CharT, char>)
> +      (void)std::vformat("{}", std::make_format_args(t));
> +#ifdef _GLIBCXX_USE_WCHAR_T
> +    else
> +      (void)std::vformat(L"{}", std::make_wformat_args(t));
> +#endif // _GLIBCXX_USE_WCHAR_T
> +    VERIFY(false);
> +  }
> +  catch (const std::format_error&)
> +  {
> +    VERIFY(true);
> +  }
> +}
> +
> +template<typename T, typename _CharT>
> +void verify(const T& t, std::basic_string_view<_CharT> str)
> +{
> +  std::basic_string<_CharT> res;
> +
> +  res = std::format(WIDEN("{}"), t);
> +  VERIFY( res == str );
> +
> +  std::basic_stringstream<_CharT> os;
> +  os << t;
> +  res = std::move(os).str();
> +  VERIFY( res == str );
> +}
> +
> +template<typename T, typename CharT>
> +void verify(const T& t, const CharT* str)
> +{ verify(t, std::basic_string_view<CharT>(str)); }
> +
>  template<typename _CharT>
>  void
>  test_padding()
> @@ -37,20 +77,6 @@ test_padding()
>    VERIFY( res == WIDEN("==16 is not a valid month==") );
>  }
>
> -template<typename T, typename _CharT>
> -void verify(const T& t, const _CharT* str)
> -{
> -  std::basic_string<_CharT> res;
> -
> -  res = std::format(WIDEN("{}"), t);
> -  VERIFY( res == str );
> -
> -  std::basic_stringstream<_CharT> os;
> -  os << t;
> -  res = std::move(os).str();
> -  VERIFY( res == str );
> -}
> -
>  template<typename Ret = void>
>  struct Rep
>  {
> @@ -553,6 +579,159 @@ test_calendar()
>    test_year_month_weekday_last<CharT>();
>  }
>
> +template<typename Clock, typename Dur, typename Dur2>
> +constexpr auto
> +wall_cast(const local_time<Dur2>& tp)
> +{
> +  using TP = time_point<Clock, std::common_type_t<Dur, days>>;
> +  if constexpr (std::is_same_v<Clock, utc_clock> || std::is_same_v<Clock,
> file_clock>)
> +    return clock_cast<Clock>(wall_cast<system_clock, Dur>(tp));
> +  else if constexpr (std::is_same_v<Clock, tai_clock>)
> +    return TP(floor<Dur>(tp.time_since_epoch()) + days(4383));
> +  else if constexpr (std::is_same_v<Clock, gps_clock>)
> +    return TP(floor<Dur>(tp.time_since_epoch()) - days(3657));
> +  else
> +    return time_point<Clock, Dur>(floor<Dur>(tp.time_since_epoch()));
> +}
> +
> +using decadays = duration<days::rep, std::ratio_multiply<std::deca,
> days::period>>;
> +using kilodays = duration<days::rep, std::ratio_multiply<std::kilo,
> days::period>>;
> +
> +template<typename _CharT, typename Clock>
> +void
> +test_time_point(bool daysAsTime)
> +{
> +  std::basic_string<_CharT> res;
> +
> +  const auto lt = local_days(2024y/March/22) + 13h + 24min + 54s +
> 111222333ns;
> +  auto strip_time = [daysAsTime](std::basic_string_view<_CharT> sv)
> +  { return daysAsTime ? sv : sv.substr(0, 10); };
> +
> +  verify( wall_cast<Clock, nanoseconds>(lt),
> +         WIDEN("2024-03-22 13:24:54.111222333") );
> +  verify( wall_cast<Clock, microseconds>(lt),
> +         WIDEN("2024-03-22 13:24:54.111222") );
> +  verify( wall_cast<Clock, milliseconds>(lt),
> +         WIDEN("2024-03-22 13:24:54.111") );
> +  verify( wall_cast<Clock, seconds>(lt),
> +         WIDEN("2024-03-22 13:24:54") );
> +  verify( wall_cast<Clock, minutes>(lt),
> +         WIDEN("2024-03-22 13:24:00") );
> +  verify( wall_cast<Clock, hours>(lt),
> +         WIDEN("2024-03-22 13:00:00") );
> +  verify( wall_cast<Clock, days>(lt),
> +         strip_time(WIDEN("2024-03-22 00:00:00")) );
> +  verify( wall_cast<Clock, decadays>(lt),
> +         strip_time(WIDEN("2024-03-18 00:00:00")) );
> +  verify( wall_cast<Clock, kilodays>(lt),
> +         strip_time(WIDEN("2022-01-08 00:00:00")) );
> +}
> +
> +template<typename _CharT>
> +void
> +test_leap_second()
> +{
> +  std::basic_string<_CharT> res;
> +
> +  const auto st = sys_days(2012y/June/30) + 23h + 59min + 59s +
> 111222333ns;
> +  auto tp = clock_cast<utc_clock>(st);
> +  tp += 1s;
> +
> +  verify( floor<nanoseconds>(tp),
> +         WIDEN("2012-06-30 23:59:60.111222333") );
> +  verify( floor<microseconds>(tp),
> +         WIDEN("2012-06-30 23:59:60.111222") );
> +  verify( floor<milliseconds>(tp),
> +         WIDEN("2012-06-30 23:59:60.111") );
> +  verify( floor<seconds>(tp),
> +         WIDEN("2012-06-30 23:59:60") );
> +}
> +
> +template<typename Dur, typename Dur2>
> +auto
> +make_zoned(const sys_time<Dur2>& st, const time_zone* tz)
> +{ return zoned_time<Dur>(tz, floor<Dur>(st)); }
> +
> +template<typename _CharT>
> +void
> +test_zoned_time()
> +{
> +  const auto st = sys_days(2024y/March/22) + 13h + 24min + 54s +
> 111222333ns;
> +  const time_zone* tz = locate_zone("Europe/Sofia");
> +  VERIFY( tz != nullptr );
> +
> +  verify( make_zoned<nanoseconds>(st, tz),
> +         WIDEN("2024-03-22 15:24:54.111222333 EET") );
> +  verify( make_zoned<microseconds>(st, tz),
> +         WIDEN("2024-03-22 15:24:54.111222 EET") );
> +  verify( make_zoned<milliseconds>(st, tz),
> +         WIDEN("2024-03-22 15:24:54.111 EET") );
> +  verify( make_zoned<seconds>(st, tz),
> +         WIDEN("2024-03-22 15:24:54 EET") );
> +  verify( make_zoned<minutes>(st, tz),
> +         WIDEN("2024-03-22 15:24:00 EET") );
> +  verify( make_zoned<hours>(st, tz),
> +         WIDEN("2024-03-22 15:00:00 EET") );
> +  verify( make_zoned<days>(st, tz),
> +         WIDEN("2024-03-22 02:00:00 EET") );
> +  verify( make_zoned<decadays>(st, tz),
> +         WIDEN("2024-03-18 02:00:00 EET") );
> +  verify( make_zoned<kilodays>(st, tz),
> +         WIDEN("2022-01-08 02:00:00 EET") );
> +}
> +
> +template<typename Dur, typename Dur2>
> +auto
> +local_fmt(const local_time<Dur2>& lt, std::string* zone)
> +{ return local_time_format(floor<Dur>(lt), zone); }
> +
> +template<typename _CharT>
> +void
> +test_local_time_format()
> +{
> +  std::basic_string<_CharT> res;
> +
> +  std::string abbrev = "Zone";
> +  const auto lt = local_days(2024y/March/22) + 13h + 24min + 54s +
> 111222333ns;
> +
> +  res = std::format(WIDEN("{}"), local_fmt<nanoseconds>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:24:54.111222333 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<microseconds>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:24:54.111222 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<milliseconds>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:24:54.111 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<seconds>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:24:54 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<minutes>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:24:00 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<hours>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 13:00:00 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<days>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-22 00:00:00 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<decadays>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2024-03-18 00:00:00 Zone") );
> +  res = std::format(WIDEN("{}"), local_fmt<kilodays>(lt, &abbrev));
> +  VERIFY( res == WIDEN("2022-01-08 00:00:00 Zone") );
> +}
> +
> +template<typename CharT>
> +void
> +test_time_points()
> +{
> +  test_time_point<CharT, local_t>(false);
> +  test_time_point<CharT, system_clock>(false);
> +  test_time_point<CharT, utc_clock>(true);
> +  test_time_point<CharT, tai_clock>(true);
> +  test_time_point<CharT, gps_clock>(true);
> +  test_time_point<CharT, file_clock>(true);
> +  test_leap_second<CharT>();
> +  test_zoned_time<CharT>();
> +  test_local_time_format<CharT>();
> +
> +  test_no_empty_spec<CharT, sys_time<years>>();
> +  test_no_empty_spec<CharT, sys_time<duration<float>>>();
> +}
> +
>  template<typename CharT>
>  void
>  test_all()
> @@ -560,6 +739,7 @@ test_all()
>    test_padding<CharT>();
>    test_durations<CharT>();
>    test_calendar<CharT>();
> +  test_time_points<CharT>();
>  }
>
>  int main()
> --
> 2.49.0
>
>

Reply via email to