Skip to content

[libc++][TZDB] Adds sys_info formatter. #85896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2024

Conversation

mordante
Copy link
Member

Implements parts of:

  • P0355 Extending to Calendars and Time Zones
  • P1361 Integration of chrono with text formatting

@mordante mordante requested a review from a team as a code owner March 20, 2024 06:08
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Mar 20, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 20, 2024

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

Changes

Implements parts of:

  • P0355 Extending <chrono> to Calendars and Time Zones
  • P1361 Integration of chrono with text formatting

Full diff: https://github.com/llvm/llvm-project/pull/85896.diff

8 Files Affected:

  • (modified) libcxx/docs/Status/FormatPaper.csv (+1-1)
  • (modified) libcxx/include/__chrono/convert_to_tm.h (+5)
  • (modified) libcxx/include/__chrono/formatter.h (+37)
  • (modified) libcxx/include/__chrono/ostream.h (+20)
  • (modified) libcxx/include/chrono (+5)
  • (added) libcxx/test/libcxx/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp (+71)
  • (added) libcxx/test/std/time/time.syn/formatter.sys_info.pass.cpp (+138)
  • (added) libcxx/test/std/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp (+48)
diff --git a/libcxx/docs/Status/FormatPaper.csv b/libcxx/docs/Status/FormatPaper.csv
index 82da54284c7386..32166ec72da753 100644
--- a/libcxx/docs/Status/FormatPaper.csv
+++ b/libcxx/docs/Status/FormatPaper.csv
@@ -24,7 +24,7 @@ Section,Description,Dependencies,Assignee,Status,First released version
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday``",,Mark de Wever,|Complete|,16.0
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::year_month_weekday_last``",,Mark de Wever,|Complete|,16.0
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::hh_mm_ss<duration<Rep, Period>>``",,Mark de Wever,|Complete|,17.0
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::sys_info``",A ``<chrono>`` implementation,Mark de Wever,,
+`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::sys_info``",,Mark de Wever,|Complete|,19.0
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::local_info``",A ``<chrono>`` implementation,Mark de Wever,,
 `[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::zoned_time<Duration, TimeZonePtr>``",A ``<chrono>`` implementation,Mark de Wever,,
 
diff --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h
index 1301cd6f1f1ada..d2c5cf922ba671 100644
--- a/libcxx/include/__chrono/convert_to_tm.h
+++ b/libcxx/include/__chrono/convert_to_tm.h
@@ -20,6 +20,7 @@
 #include <__chrono/month_weekday.h>
 #include <__chrono/monthday.h>
 #include <__chrono/statically_widen.h>
+#include <__chrono/sys_info.h>
 #include <__chrono/system_clock.h>
 #include <__chrono/time_point.h>
 #include <__chrono/weekday.h>
@@ -171,6 +172,10 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
       if (__value.hours().count() > std::numeric_limits<decltype(__result.tm_hour)>::max())
         std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow");
     __result.tm_hour = __value.hours().count();
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  } else if constexpr (same_as<_ChronoT, chrono::sys_info>) {
+    // Has no time information.
+#  endif
   } else
     static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization");
 
diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h
index 8b8592041a1fb9..f5474e3ea6d078 100644
--- a/libcxx/include/__chrono/formatter.h
+++ b/libcxx/include/__chrono/formatter.h
@@ -24,6 +24,7 @@
 #include <__chrono/ostream.h>
 #include <__chrono/parser_std_format_spec.h>
 #include <__chrono/statically_widen.h>
+#include <__chrono/sys_info.h>
 #include <__chrono/system_clock.h>
 #include <__chrono/time_point.h>
 #include <__chrono/weekday.h>
@@ -202,6 +203,12 @@ struct _LIBCPP_HIDE_FROM_ABI __time_zone {
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const _Tp& __value) {
   __time_zone __result;
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  if constexpr (same_as<_Tp, chrono::sys_info>) {
+    __result.__offset = __value.offset;
+    __result.__abbrev = __value.abbrev;
+  }
+#  endif
   return __result;
 }
 
@@ -411,6 +418,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) {
     return __value.weekday().ok();
   else if constexpr (__is_hh_mm_ss<_Tp>)
     return true;
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  else if constexpr (same_as<_Tp, chrono::sys_info>)
+    return true;
+#  endif
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -451,6 +462,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) {
     return __value.weekday().ok();
   else if constexpr (__is_hh_mm_ss<_Tp>)
     return true;
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  else if constexpr (same_as<_Tp, chrono::sys_info>)
+    return true;
+#  endif
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -491,6 +506,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) {
     return __value.ok();
   else if constexpr (__is_hh_mm_ss<_Tp>)
     return true;
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  else if constexpr (same_as<_Tp, chrono::sys_info>)
+    return true;
+#  endif
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -531,6 +550,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) {
     return __value.month().ok();
   else if constexpr (__is_hh_mm_ss<_Tp>)
     return true;
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+  else if constexpr (same_as<_Tp, chrono::sys_info>)
+    return true;
+#  endif
   else
     static_assert(sizeof(_Tp) == 0, "Add the missing type specialization");
 }
@@ -860,6 +883,20 @@ struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chron
     return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time);
   }
 };
+
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+template <__fmt_char_type _CharT>
+struct formatter<chrono::sys_info, _CharT> : public __formatter_chrono<_CharT> {
+public:
+  using _Base = __formatter_chrono<_CharT>;
+
+  template <class _ParseContext>
+  _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
+    return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time_zone);
+  }
+};
+#  endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
 #endif // if _LIBCPP_STD_VER >= 20
 
 _LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__chrono/ostream.h b/libcxx/include/__chrono/ostream.h
index b687ef8059d5f5..68ddb1d6cd2e13 100644
--- a/libcxx/include/__chrono/ostream.h
+++ b/libcxx/include/__chrono/ostream.h
@@ -19,6 +19,7 @@
 #include <__chrono/month_weekday.h>
 #include <__chrono/monthday.h>
 #include <__chrono/statically_widen.h>
+#include <__chrono/sys_info.h>
 #include <__chrono/system_clock.h>
 #include <__chrono/weekday.h>
 #include <__chrono/year.h>
@@ -262,6 +263,25 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms
   return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms);
 }
 
+#  if !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
+template <class _CharT, class _Traits>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) {
+  // __info.abbrev is always std::basic_string<char>.
+  // Since these strings typically are short the conversion should be cheap.
+  std::basic_string<_CharT> __abbrev{__info.abbrev.begin(), __info.abbrev.end()};
+  return __os << std::format(
+             _LIBCPP_STATICALLY_WIDEN(_CharT, "[{}, {}) {:%T} {:%Q%q} {}"),
+             __info.begin,
+             __info.end,
+             hh_mm_ss{__info.offset},
+             __info.save,
+             __abbrev);
+}
+
+#  endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_TZDB)
+
 } // namespace chrono
 
 #endif // if _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 00b940a6610a3a..c068bbef73245b 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -733,6 +733,10 @@ struct sys_info {
   string        abbrev;
 };
 
+template<class charT, class traits>                                              // C++20
+  basic_ostream<charT, traits>&
+    operator<<(basic_ostream<charT, traits>& os, const sys_info& si);
+
 // 25.10.5, class time_zone                                                      // C++20
 enum class choose {earliest, latest};
 class time_zone {
@@ -829,6 +833,7 @@ namespace std {
   template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20
   template<class Rep, class Period, class charT>
     struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>;             // C++20
+  template<class charT> struct formatter<chrono::sys_info, charT>;                // C++20
 } // namespace std
 
 namespace chrono {
diff --git a/libcxx/test/libcxx/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp b/libcxx/test/libcxx/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
new file mode 100644
index 00000000000000..26a8ddd3bfbad9
--- /dev/null
+++ b/libcxx/test/libcxx/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-localization
+
+// XFAIL: libcpp-has-no-incomplete-tzdb
+
+// <chrono>
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const sys_info& r);
+
+// [time.zone.info.sys]
+//   7 Effects: Streams out the sys_info object r in an unspecified format.
+//   8 Returns: os.
+//
+// Tests the output produced by this function.
+
+#include <cassert>
+#include <chrono>
+#include <memory>
+#include <sstream>
+
+#include "assert_macros.h"
+#include "test_macros.h"
+#include "make_string.h"
+#include "concat_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT>
+static void test(std::basic_string_view<CharT> expected, std::chrono::sys_info&& info) {
+  std::basic_stringstream<CharT> sstr;
+  sstr << info;
+  std::basic_string<CharT> output = sstr.str();
+
+  TEST_REQUIRE(expected == output,
+               TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output   ", output, '\n'));
+}
+
+template <class CharT>
+static void test() {
+  using namespace std::literals::chrono_literals;
+  namespace tz = std::chrono;
+
+  test(SV("[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min TZ"),
+       tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"});
+
+  test(SV("[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min DMY"),
+       tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+                    static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+                    12h + 23min + 45s,
+                    -67min,
+                    "DMY"});
+}
+
+int main(int, const char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/time/time.syn/formatter.sys_info.pass.cpp b/libcxx/test/std/time/time.syn/formatter.sys_info.pass.cpp
new file mode 100644
index 00000000000000..53da20668c64f5
--- /dev/null
+++ b/libcxx/test/std/time/time.syn/formatter.sys_info.pass.cpp
@@ -0,0 +1,138 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-localization
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// TODO FMT This test should not require std::to_chars(floating-point)
+// XFAIL: availability-fp_to_chars-missing
+
+// XFAIL: libcpp-has-no-incomplete-tzdb
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+//
+// template<class charT> struct formatter<chrono::sys_info, charT>;
+
+#include <chrono>
+#include <format>
+
+#include <cassert>
+#include <concepts>
+#include <locale>
+#include <iostream>
+#include <type_traits>
+
+#include "formatter_tests.h"
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+template <class CharT>
+static void test_no_chrono_specs() {
+// This test libc++ specific due to
+// [time.zone.info.sys]/7
+//   Effects: Streams out the sys_info object r in an unspecified format.
+#ifdef _LIBCPP_VERSION
+  using namespace std::literals::chrono_literals;
+  namespace tz = std::chrono;
+
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output
+
+  check(SV("[-10484-10-16 15:30:08, 14423-03-17 15:30:07) 00:00:00 0min TZ"),
+        SV("{}"),
+        tz::sys_info{tz::sys_seconds::min(), tz::sys_seconds::max(), 0s, 0min, "TZ"});
+
+  check(SV("[1970-01-01 00:00:00, 2038-12-31 00:00:00) 12:23:45 -67min DMY"),
+        SV("{}"),
+        tz::sys_info{static_cast<tz::sys_days>(tz::year_month_day{1970y, tz::January, 1d}),
+                     static_cast<tz::sys_days>(tz::year_month_day{2038y, tz::December, 31d}),
+                     12h + 23min + 45s,
+                     -67min,
+                     "DMY"});
+
+  std::locale::global(std::locale::classic());
+#endif // _LIBCPP_VERSION
+}
+
+template <class CharT>
+static void test_valid_values() {
+  using namespace std::literals::chrono_literals;
+
+  constexpr std::basic_string_view<CharT> fmt  = SV("{:%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
+  constexpr std::basic_string_view<CharT> lfmt = SV("{:L%%z='%z'%t%%Ez='%Ez'%t%%Oz='%Oz'%t%%Z='%Z'%n}");
+
+  const std::locale loc(LOCALE_ja_JP_UTF_8);
+  std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
+
+  // Non localized output using C-locale
+  check(SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"),
+        fmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"});
+
+  check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"),
+        fmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"});
+
+  check(SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"),
+        fmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"});
+
+  // Use the global locale (fr_FR)
+  check(SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"});
+
+  check(SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"});
+
+  check(SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"});
+
+  // Use supplied locale (ja_JP).
+  check(loc,
+        SV("%z='-0200'\t%Ez='-02:00'\t%Oz='-02:00'\t%Z='NEG'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, -2h, 0min, "NEG"});
+
+  check(loc,
+        SV("%z='+0000'\t%Ez='+00:00'\t%Oz='+00:00'\t%Z='ZERO'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 0s, 0min, "ZERO"});
+
+  check(loc,
+        SV("%z='+1115'\t%Ez='+11:15'\t%Oz='+11:15'\t%Z='POS'\n"),
+        lfmt,
+        std::chrono::sys_info{std::chrono::sys_seconds{0s}, std::chrono::sys_seconds{0s}, 11h + 15min, 0min, "POS"});
+
+  std::locale::global(std::locale::classic());
+}
+
+template <class CharT>
+static void test() {
+  test_no_chrono_specs<CharT>();
+  test_valid_values<CharT>();
+
+  check_invalid_types<CharT>({SV("z"), SV("Z"), SV("Ez"), SV("Oz")}, std::chrono::sys_info{});
+}
+
+int main(int, char**) {
+  test<char>();
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/std/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp b/libcxx/test/std/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
new file mode 100644
index 00000000000000..4edbdb065b1c90
--- /dev/null
+++ b/libcxx/test/std/time/time.zone/time.zone.info/time.zone.info.sys/ostream.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: no-localization
+
+// XFAIL: libcpp-has-no-incomplete-tzdb
+
+// <chrono>
+
+// template<class charT, class traits>
+//   basic_ostream<charT, traits>&
+//     operator<<(basic_ostream<charT, traits>& os, const sys_info& r);
+
+// [time.zone.info.sys]
+//   7 Effects: Streams out the sys_info object r in an unspecified format.
+//   8 Returns: os.
+//
+// There is a private libc++ test that validates the exact output.
+
+#include <cassert>
+#include <chrono>
+#include <memory>
+#include <sstream>
+
+#include "test_macros.h"
+
+template <class CharT>
+static void test() {
+  std::chrono::sys_info s;
+  std::basic_ostringstream<CharT> os;
+  std::basic_ostream<CharT>& result = std::chrono::operator<<(os, s);
+  assert(std::addressof(result) == std::addressof(os));
+}
+
+int main(int, const char**) {
+  test<char>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+  test<wchar_t>();
+#endif
+
+  return 0;
+}

@mordante mordante force-pushed the users/mordante/adds_formatter_sys_info branch 7 times, most recently from 3eaa059 to 73e4a9e Compare March 21, 2024 18:32
@mordante mordante changed the base branch from users/mordante/fixes_chrono_formatter_time_zone_information to users/mordante/improves_chrono_year_formatting March 21, 2024 18:33
@mordante mordante force-pushed the users/mordante/improves_chrono_year_formatting branch from f3e7b58 to 677956d Compare April 10, 2024 18:45
@mordante mordante force-pushed the users/mordante/adds_formatter_sys_info branch 3 times, most recently from e6ae1f0 to 96bc907 Compare April 13, 2024 11:44
@mordante mordante force-pushed the users/mordante/improves_chrono_year_formatting branch from 677956d to 96fbdc0 Compare April 17, 2024 06:09
Base automatically changed from users/mordante/improves_chrono_year_formatting to main April 17, 2024 15:02
Implements parts of:
- P0355 Extending <chrono> to Calendars and Time Zones
- P1361 Integration of chrono with text formatting
@mordante mordante force-pushed the users/mordante/adds_formatter_sys_info branch from 96bc907 to c75ae7b Compare April 17, 2024 15:04
@mordante mordante merged commit 6f7976c into main Apr 17, 2024
@mordante mordante deleted the users/mordante/adds_formatter_sys_info branch April 17, 2024 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants