-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[libc++][chrono] implements TAI clock. #125550
Conversation
Implements parts of: - P0355 Extending <chrono> to Calendars and Time Zones - P1361 Integration of chrono with text formatting - LWG3359 <chrono> leap second support should allow for negative leap seconds
@llvm/pr-subscribers-libcxx Author: Mark de Wever (mordante) ChangesImplements parts of:
Patch is 78.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125550.diff 17 Files Affected:
diff --git a/libcxx/docs/Status/FormatPaper.csv b/libcxx/docs/Status/FormatPaper.csv
index 343fa62f135654..de64e9c25a7771 100644
--- a/libcxx/docs/Status/FormatPaper.csv
+++ b/libcxx/docs/Status/FormatPaper.csv
@@ -3,7 +3,7 @@ Section,Description,Dependencies,Assignee,Status,First released version
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::duration<Rep, Period>``",,Mark de Wever,|Complete|,16
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::sys_time<Duration>``",,Mark de Wever,|Complete|,17
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::utc_time<Duration>``",A ``<chrono>`` implementation,Mark de Wever,|Complete|,20
-`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::tai_time<Duration>``",A ``<chrono>`` implementation,Mark de Wever,,,
++`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::tai_time<Duration>``",,Mark de Wever,|Complete|,21
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::gps_time<Duration>``",A ``<chrono>`` implementation,Mark de Wever,,,
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::file_time<Duration>``",,Mark de Wever,|Complete|,17
`[time.syn] <https://wg21.link/time.syn>`_,"Formatter ``chrono::local_time<Duration>``",,Mark de Wever,|Complete|,17
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 8dac823503d73f..ce805b4eb7b8b4 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -270,6 +270,7 @@ set(files
__chrono/steady_clock.h
__chrono/sys_info.h
__chrono/system_clock.h
+ __chrono/tai_clock.h
__chrono/time_point.h
__chrono/time_zone.h
__chrono/time_zone_link.h
diff --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h
index 7d06a38d87f26d..934293ce382345 100644
--- a/libcxx/include/__chrono/convert_to_tm.h
+++ b/libcxx/include/__chrono/convert_to_tm.h
@@ -23,6 +23,7 @@
#include <__chrono/statically_widen.h>
#include <__chrono/sys_info.h>
#include <__chrono/system_clock.h>
+#include <__chrono/tai_clock.h>
#include <__chrono/time_point.h>
#include <__chrono/utc_clock.h>
#include <__chrono/weekday.h>
@@ -112,6 +113,16 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(chrono::utc_time<_Duration> __tp) {
return __result;
}
+template <class _Tm, class _Duration>
+_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(chrono::tai_time<_Duration> __tp) {
+ using _Rp = common_type_t<_Duration, chrono::seconds>;
+ // The time between the TAI epoch (1958-01-01) and UNIX epoch (1970-01-01).
+ // This avoids leap second conversion when going from TAI to UTC.
+ // (It also avoids issues when the date is before the UTC epoch.)
+ constexpr chrono::seconds __offset{4383 * 24 * 60 * 60};
+ return std::__convert_to_tm<_Tm>(chrono::sys_time<_Rp>{__tp.time_since_epoch() - __offset});
+}
+
# endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
# endif // _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
@@ -131,6 +142,8 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) {
# if _LIBCPP_HAS_EXPERIMENTAL_TZDB
else if constexpr (same_as<typename _ChronoT::clock, chrono::utc_clock>)
return std::__convert_to_tm<_Tm>(__value);
+ else if constexpr (same_as<typename _ChronoT::clock, chrono::tai_clock>)
+ return std::__convert_to_tm<_Tm>(__value);
# endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
# endif // _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
else if constexpr (same_as<typename _ChronoT::clock, chrono::file_clock>)
diff --git a/libcxx/include/__chrono/formatter.h b/libcxx/include/__chrono/formatter.h
index d17acd274e4cda..753a824a3c50d7 100644
--- a/libcxx/include/__chrono/formatter.h
+++ b/libcxx/include/__chrono/formatter.h
@@ -31,6 +31,7 @@
# include <__chrono/statically_widen.h>
# include <__chrono/sys_info.h>
# include <__chrono/system_clock.h>
+# include <__chrono/tai_clock.h>
# include <__chrono/time_point.h>
# include <__chrono/utc_clock.h>
# include <__chrono/weekday.h>
@@ -231,6 +232,8 @@ _LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const
# if _LIBCPP_HAS_EXPERIMENTAL_TZDB
if constexpr (same_as<_Tp, chrono::sys_info>)
return {__value.abbrev, __value.offset};
+ else if constexpr (__is_time_point<_Tp> && requires { requires same_as<typename _Tp::clock, chrono::tai_clock>; })
+ return {"TAI", chrono::seconds{0}};
# if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>)
return __formatter::__convert_to_time_zone(__value.get_info());
@@ -734,6 +737,17 @@ struct _LIBCPP_TEMPLATE_VIS formatter<chrono::utc_time<_Duration>, _CharT> : pub
}
};
+template <class _Duration, __fmt_char_type _CharT>
+struct _LIBCPP_TEMPLATE_VIS formatter<chrono::tai_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> {
+public:
+ using _Base _LIBCPP_NODEBUG = __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::__clock);
+ }
+};
+
# endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
# endif // _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
diff --git a/libcxx/include/__chrono/ostream.h b/libcxx/include/__chrono/ostream.h
index ed9ad8e346ba94..b8cd6a4680662b 100644
--- a/libcxx/include/__chrono/ostream.h
+++ b/libcxx/include/__chrono/ostream.h
@@ -26,6 +26,7 @@
# include <__chrono/statically_widen.h>
# include <__chrono/sys_info.h>
# include <__chrono/system_clock.h>
+# include <__chrono/tai_clock.h>
# include <__chrono/utc_clock.h>
# include <__chrono/weekday.h>
# include <__chrono/year.h>
@@ -71,6 +72,12 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const utc_time<_Duration>& __tp
return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
}
+template <class _CharT, class _Traits, class _Duration>
+_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
+operator<<(basic_ostream<_CharT, _Traits>& __os, const tai_time<_Duration>& __tp) {
+ return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp);
+}
+
# endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
# endif // _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM
diff --git a/libcxx/include/__chrono/tai_clock.h b/libcxx/include/__chrono/tai_clock.h
new file mode 100644
index 00000000000000..18ba329b7b8fb4
--- /dev/null
+++ b/libcxx/include/__chrono/tai_clock.h
@@ -0,0 +1,98 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___CHRONO_TAI_CLOCK_H
+#define _LIBCPP___CHRONO_TAI_CLOCK_H
+
+#include <version>
+// Enable the contents of the header only when libc++ was built with experimental features enabled.
+#if _LIBCPP_HAS_EXPERIMENTAL_TZDB
+
+# include <__chrono/duration.h>
+# include <__chrono/time_point.h>
+# include <__chrono/utc_clock.h>
+# include <__config>
+# include <__type_traits/common_type.h>
+
+# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+# endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+# if _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
+
+namespace chrono {
+
+class tai_clock;
+
+template <class _Duration>
+using tai_time = time_point<tai_clock, _Duration>;
+using tai_seconds = tai_time<seconds>;
+
+// [time.clock.tai.overview]/1
+// The clock tai_clock measures seconds since 1958-01-01 00:00:00 and is
+// offset 10s ahead of UTC at this date. That is, 1958-01-01 00:00:00 TAI is
+// equivalent to 1957-12-31 23:59:50 UTC. Leap seconds are not inserted into
+// TAI. Therefore every time a leap second is inserted into UTC, UTC shifts
+// another second with respect to TAI. For example by 2000-01-01 there had
+// been 22 positive and 0 negative leap seconds inserted so 2000-01-01
+// 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI (22s plus the
+// initial 10s offset).
+//
+// Note this does not specify what the UTC offset before 1958-01-01 00:00:00
+// TAI is. However the member functions are fully specified in the standard.
+// https://koka-lang.github.io/koka/doc/std_time_utc.html contains more
+// information and references.
+class tai_clock {
+public:
+ using rep = utc_clock::rep;
+ using period = utc_clock::period;
+ using duration = chrono::duration<rep, period>;
+ using time_point = chrono::time_point<tai_clock>;
+ static constexpr bool is_steady = false; // The utc_clock is not steady.
+
+ // The static difference between UTC and TAI time.
+ static constexpr chrono::seconds __offset{378691210};
+
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static time_point now() { return from_utc(utc_clock::now()); }
+
+ template <class _Duration>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static utc_time<common_type_t<_Duration, seconds>>
+ to_utc(const tai_time<_Duration>& __time) noexcept {
+ using _Rp = common_type_t<_Duration, seconds>;
+ _Duration __time_since_epoch = __time.time_since_epoch();
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__time_since_epoch >= utc_time<_Rp>::min().time_since_epoch() + __offset,
+ "the TAI to UTC conversion would underflow");
+
+ return utc_time<_Rp>{__time_since_epoch - __offset};
+ }
+
+ template <class _Duration>
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static tai_time<common_type_t<_Duration, seconds>>
+ from_utc(const utc_time<_Duration>& __time) noexcept {
+ using _Rp = common_type_t<_Duration, seconds>;
+ _Duration __time_since_epoch = __time.time_since_epoch();
+ _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__time_since_epoch <= utc_time<_Rp>::max().time_since_epoch() - __offset,
+ "the UTC to TAI conversion would overflow");
+
+ return tai_time<_Rp>{__time_since_epoch + __offset};
+ }
+};
+
+} // namespace chrono
+
+# endif // _LIBCPP_STD_VER >= 20 && _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM &&
+ // _LIBCPP_HAS_LOCALIZATION
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
+
+#endif // _LIBCPP___CHRONO_TAI_CLOCK_H
diff --git a/libcxx/include/chrono b/libcxx/include/chrono
index 10695eea649fb7..bd4c98600440c4 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -335,6 +335,34 @@ struct leap_second_info { // C++20
template<class Duration> // C++20
leap_second_info get_leap_second_info(const utc_time<Duration>& ut);
+
+// [time.clock.tai], class tai_clock
+class tai_clock { // C++20
+public:
+ using rep = a signed arithmetic type;
+ using period = ratio<unspecified, unspecified>;
+ using duration = chrono::duration<rep, period>;
+ using time_point = chrono::time_point<tai_clock>;
+ static constexpr bool is_steady = unspecified;
+
+ static time_point now();
+
+ template<class Duration>
+ static utc_time<common_type_t<Duration, seconds>>
+ to_utc(const tai_time<Duration>& t);
+ template<class Duration>
+ static tai_time<common_type_t<Duration, seconds>>
+ from_utc(const utc_time<Duration>& t);
+};
+
+template<class Duration>
+using tai_time = time_point<tai_clock, Duration>; // C++20
+using tai_seconds = tai_time<seconds>; // C++20
+
+template<class charT, class traits, class Duration> // C++20
+ basic_ostream<charT, traits>&
+ operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& t);
+
class file_clock // C++20
{
public:
@@ -898,6 +926,8 @@ namespace std {
struct formatter<chrono::sys_time<Duration>, charT>; // C++20
template<class Duration, class charT>
struct formatter<chrono::utc_time<Duration>, charT>; // C++20
+ template<class Duration, class charT>
+ struct formatter<chrono::tai_time<Duration>, charT>; // C++20
template<class Duration, class charT>
struct formatter<chrono::filetime<Duration>, charT>; // C++20
template<class Duration, class charT>
@@ -1014,6 +1044,7 @@ constexpr chrono::year operator ""y(unsigned lo
# if _LIBCPP_HAS_TIME_ZONE_DATABASE && _LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION
# include <__chrono/leap_second.h>
+# include <__chrono/tai_clock.h>
# include <__chrono/time_zone.h>
# include <__chrono/time_zone_link.h>
# include <__chrono/tzdb.h>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 4bae02137b37b2..fd39c946b992a4 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -967,6 +967,10 @@ module std [system] {
header "__chrono/system_clock.h"
export std.chrono.time_point
}
+ module tai_clock {
+ header "__chrono/tai_clock.h"
+ export std.chrono.time_point
+ }
module time_point { header "__chrono/time_point.h" }
module time_zone_link { header "__chrono/time_zone_link.h" }
module time_zone { header "__chrono/time_zone.h" }
diff --git a/libcxx/modules/std/chrono.inc b/libcxx/modules/std/chrono.inc
index 98f14f716c2078..43e8da36e90448 100644
--- a/libcxx/modules/std/chrono.inc
+++ b/libcxx/modules/std/chrono.inc
@@ -97,13 +97,13 @@ export namespace std {
using std::chrono::get_leap_second_info;
-# if 0
// [time.clock.tai], class tai_clock
using std::chrono::tai_clock;
using std::chrono::tai_seconds;
using std::chrono::tai_time;
+# if 0
// [time.clock.gps], class gps_clock
using std::chrono::gps_clock;
diff --git a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
index 644c5b598c018d..bb40e0cfc4e1b8 100644
--- a/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/diagnostics/chrono.nodiscard.verify.cpp
@@ -102,4 +102,15 @@ void test(std::chrono::time_zone tz, std::chrono::time_zone_link link, std::chro
zt.get_sys_time(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
zt.get_info(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
+
+ { // [time.clock.tai]
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::now();
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::to_utc(std::chrono::tai_seconds{});
+
+ // expected-warning@+1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+ std::chrono::tai_clock::from_utc(std::chrono::utc_seconds{});
+ }
}
diff --git a/libcxx/test/std/time/time.clock/time.clock.tai/tai_time.ostream.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.tai/tai_time.ostream.pass.cpp
new file mode 100644
index 00000000000000..3508ceb8b2d3f6
--- /dev/null
+++ b/libcxx/test/std/time/time.clock/time.clock.tai/tai_time.ostream.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++20
+// UNSUPPORTED: no-filesystem, no-localization, no-tzdb
+// 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
+// XFAIL: availability-tzdb-missing
+
+// REQUIRES: locale.fr_FR.UTF-8
+// REQUIRES: locale.ja_JP.UTF-8
+
+// <chrono>
+
+// class taitem_clock;
+
+// template<class charT, class traits, class Duration>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& tp);
+
+#include <chrono>
+#include <cassert>
+#include <ratio>
+#include <sstream>
+
+#include "make_string.h"
+#include "platform_support.h" // locale name macros
+#include "test_macros.h"
+
+#define SV(S) MAKE_STRING_VIEW(CharT, S)
+
+template <class CharT, class Duration>
+static std::basic_string<CharT> stream_c_locale(std::chrono::tai_time<Duration> time_point) {
+ std::basic_stringstream<CharT> sstr;
+ sstr << std::fixed << time_point;
+ return sstr.str();
+}
+
+template <class CharT, class Duration>
+static std::basic_string<CharT> stream_fr_FR_locale(std::chrono::tai_time<Duration> time_point) {
+ std::basic_stringstream<CharT> sstr;
+ const std::locale locale(LOCALE_fr_FR_UTF_8);
+ sstr.imbue(locale);
+ sstr << std::fixed << time_point;
+ return sstr.str();
+}
+
+template <class CharT, class Duration>
+static std::basic_string<CharT> stream_ja_JP_locale(std::chrono::tai_time<Duration> time_point) {
+ std::basic_stringstream<CharT> sstr;
+ const std::locale locale(LOCALE_ja_JP_UTF_8);
+ sstr.imbue(locale);
+ sstr << std::fixed << time_point;
+ return sstr.str();
+}
+
+template <class CharT>
+static void test_c() {
+ using namespace std::literals::chrono_literals;
+ namespace cr = std::chrono;
+
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::nanoseconds>{946'688'523'123'456'789ns}) ==
+ SV("1988-01-01 01:02:03.123456789"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::microseconds>{946'688'523'123'456us}) ==
+ SV("1988-01-01 01:02:03.123456"));
+
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::milliseconds>{946'684'822'123ms}) == SV("1988-01-01 00:00:22.123"));
+ assert(stream_c_locale<CharT>(cr::tai_seconds{1'234'567'890s}) == SV("1997-02-13 23:31:30"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::minutes>{20'576'131min}) == SV("1997-02-13 23:31:00"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::hours>{342'935h}) == SV("1997-02-13 23:00:00"));
+
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::duration<signed char, std::ratio<2, 1>>>{
+ cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1958-01-01 00:02:00"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::duration<short, std::ratio<1, 2>>>{
+ cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1958-01-01 00:30:00.0"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::duration<int, std::ratio<1, 4>>>{
+ cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1958-01-01 00:15:00.00"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::duration<long, std::ratio<1, 10>>>{
+ cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1958-01-01 01:01:01.1"));
+ assert(stream_c_locale<CharT>(cr::tai_time<cr::duration<long long, std::ratio<1, 100>>>{
+ cr::duration<long long, std::ratio<1, 100>>{12'345'678'9010}}) == SV("1997-02-13 23:31:30.10"));
+}
+
+template <class CharT>
+static void test_fr_FR() {
+ using namespace std::literals::chrono_literals;
+ namespace cr = std::chrono;
+
+ assert(stream_fr_FR_locale<CharT>(cr::tai_time<cr::nanoseconds>{946'688'523'123'456'789ns}) ==
+ SV("1988-01-01 01:02:03,123456789"));
+ assert(stream_fr_FR_locale<CharT>(cr::tai_time<cr::microseconds>{946'688'523'123'456us}) ==
+ SV("1988-01-01 01:02:03,123456"));
+
+ assert(stream_fr_FR_locale<CharT>(cr::tai_time<cr::milliseconds>{946'684'822'123ms}) ==
+ SV("1988-01-01 00:00:22,123"));
+ assert(str...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM with minor comments applied.
@@ -11,6 +11,7 @@ | |||
|
|||
#include <cstdio> | |||
#include <string> | |||
#include <source_location> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is C++20 only, this might require a TEST_STD_VER
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually the file already is mostly C++20, so the check is already there.
libcxx/test/std/time/time.clock/time.clock.tai/tai_time.ostream.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/time/time.clock/time.clock.tai/time.clock.tai.members/from_utc.pass.cpp
Show resolved
Hide resolved
//===----------------------------------------------------------------------===// | ||
|
||
// REQUIRES: std-at-least-c++20 | ||
// UNSUPPORTED: no-filesystem, no-localization, no-tzdb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably makes sense to only use UNSUPPORTED: no-tzdb
here. The tzdb
feature should probably depend on the filesystem
feature.
e3c4749
to
0858a05
Compare
Implements parts of: - P0355 Extending <chrono> to Calendars and Time Zones - P1361 Integration of chrono with text formatting - LWG3359 <chrono> leap second support should allow for negative leap seconds
Implements parts of: