[libcxx-commits] [libcxx] [libc++] fix `gps_time` formatting and related tests (PR #181560)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Feb 15 10:29:01 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Matt Stephanson (MattStephanson)
<details>
<summary>Changes</summary>
- The Standard wording, [[time.format]/13](https://eel.is/c++draft/time.format#<!-- -->13), is similar to TAI formatting in that it's equivalent to formatting a `sys_time` with a fixed offset. Leap seconds should not be considered.
- Tests need to be adjusted by adding the number of leap seconds between the GPS epoch and the tested date, which is 15s for 2010 and 18s for 2019.
- The TAI and GPS tests using `meow_time<cr::duration<long, std::ratio<1, 10>>>` should use `long long` because the offset will overflow a 32-bit signed integer.
---
Full diff: https://github.com/llvm/llvm-project/pull/181560.diff
3 Files Affected:
- (modified) libcxx/include/__chrono/convert_to_tm.h (+4-1)
- (modified) libcxx/test/std/time/time.clock/time.clock.gps/gps_time.ostream.pass.cpp (+27-27)
- (modified) libcxx/test/std/time/time.clock/time.clock.tai/tai_time.ostream.pass.cpp (+6-6)
``````````diff
diff --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h
index 817e6747a789f..16e1415238c2b 100644
--- a/libcxx/include/__chrono/convert_to_tm.h
+++ b/libcxx/include/__chrono/convert_to_tm.h
@@ -127,7 +127,10 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(chrono::tai_time<_Duration> __tp) {
template <class _Tm, class _Duration>
_LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(chrono::gps_time<_Duration> __tp) {
- return std::__convert_to_tm<_Tm>(chrono::utc_clock::to_sys(chrono::gps_clock::to_utc(__tp)));
+ using _Rp = common_type_t<_Duration, chrono::seconds>;
+ // The time between the GPS epoch (1980-01-06) and UNIX epoch (1970-01-01).
+ constexpr chrono::seconds __offset{3657 * 24 * 60 * 60};
+ return std::__convert_to_tm<_Tm>(chrono::sys_time<_Rp>{__tp.time_since_epoch() + __offset});
}
# endif // _LIBCPP_HAS_EXPERIMENTAL_TZDB
diff --git a/libcxx/test/std/time/time.clock/time.clock.gps/gps_time.ostream.pass.cpp b/libcxx/test/std/time/time.clock/time.clock.gps/gps_time.ostream.pass.cpp
index 3f942bc63ce5a..25201a4dc1129 100644
--- a/libcxx/test/std/time/time.clock/time.clock.gps/gps_time.ostream.pass.cpp
+++ b/libcxx/test/std/time/time.clock/time.clock.gps/gps_time.ostream.pass.cpp
@@ -69,14 +69,14 @@ static void test_c() {
namespace cr = std::chrono;
assert(stream_c_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) ==
- SV("2010-01-05 01:01:48.123456789"));
+ SV("2010-01-05 01:02:03.123456789"));
assert(stream_c_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) ==
- SV("2010-01-05 01:01:48.123456"));
+ SV("2010-01-05 01:02:03.123456"));
- assert(stream_c_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) == SV("2010-01-05 00:00:07.123"));
- assert(stream_c_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12"));
- assert(stream_c_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42"));
- assert(stream_c_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42"));
+ assert(stream_c_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) == SV("2010-01-05 00:00:22.123"));
+ assert(stream_c_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:30"));
+ assert(stream_c_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:31:00"));
+ assert(stream_c_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 23:00:00"));
assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{
cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00"));
@@ -84,10 +84,10 @@ static void test_c() {
cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00.0"));
assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{
cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00.00"));
- assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{
- cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1"));
+ assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 10>>>{
+ cr::duration<long long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1"));
assert(stream_c_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{
- cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12.10"));
+ cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:30.10"));
}
template <class CharT>
@@ -96,15 +96,15 @@ static void test_fr_FR() {
namespace cr = std::chrono;
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) ==
- SV("2010-01-05 01:01:48,123456789"));
+ SV("2010-01-05 01:02:03,123456789"));
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) ==
- SV("2010-01-05 01:01:48,123456"));
+ SV("2010-01-05 01:02:03,123456"));
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) ==
- SV("2010-01-05 00:00:07,123"));
- assert(stream_fr_FR_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12"));
- assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42"));
- assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42"));
+ SV("2010-01-05 00:00:22,123"));
+ assert(stream_fr_FR_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:30"));
+ assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:31:00"));
+ assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 23:00:00"));
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{
cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00"));
@@ -112,10 +112,10 @@ static void test_fr_FR() {
cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00,0"));
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{
cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00,00"));
- assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{
- cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01,1"));
+ assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 10>>>{
+ cr::duration<long long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01,1"));
assert(stream_fr_FR_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{
- cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12,10"));
+ cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:30,10"));
}
template <class CharT>
@@ -124,15 +124,15 @@ static void test_ja_JP() {
namespace cr = std::chrono;
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::nanoseconds>{946'688'523'123'456'789ns}) ==
- SV("2010-01-05 01:01:48.123456789"));
+ SV("2010-01-05 01:02:03.123456789"));
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::microseconds>{946'688'523'123'456us}) ==
- SV("2010-01-05 01:01:48.123456"));
+ SV("2010-01-05 01:02:03.123456"));
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::milliseconds>{946'684'822'123ms}) ==
- SV("2010-01-05 00:00:07.123"));
- assert(stream_ja_JP_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:12"));
- assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:30:42"));
- assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 22:59:42"));
+ SV("2010-01-05 00:00:22.123"));
+ assert(stream_ja_JP_locale<CharT>(cr::gps_seconds{1'234'567'890s}) == SV("2019-02-18 23:31:30"));
+ assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::minutes>{20'576'131min}) == SV("2019-02-18 23:31:00"));
+ assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::hours>{342'935h}) == SV("2019-02-18 23:00:00"));
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<signed char, std::ratio<2, 1>>>{
cr::duration<signed char, std::ratio<2, 1>>{60}}) == SV("1980-01-06 00:02:00"));
@@ -140,10 +140,10 @@ static void test_ja_JP() {
cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1980-01-06 00:30:00.0"));
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<int, std::ratio<1, 4>>>{
cr::duration<int, std::ratio<1, 4>>{3600}}) == SV("1980-01-06 00:15:00.00"));
- assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<long, std::ratio<1, 10>>>{
- cr::duration<long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1"));
+ assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 10>>>{
+ cr::duration<long long, std::ratio<1, 10>>{36611}}) == SV("1980-01-06 01:01:01.1"));
assert(stream_ja_JP_locale<CharT>(cr::gps_time<cr::duration<long long, std::ratio<1, 100>>>{
- cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:12.10"));
+ cr::duration<long long, std::ratio<1, 100>>{123'456'789'010}}) == SV("2019-02-18 23:31:30.10"));
}
template <class CharT>
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
index e4f953118fd43..1ca9f18e99646 100644
--- 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
@@ -84,8 +84,8 @@ static void test_c() {
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, 10>>>{
+ cr::duration<long 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"));
}
@@ -112,8 +112,8 @@ static void test_fr_FR() {
cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1958-01-01 00:30:00,0"));
assert(stream_fr_FR_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_fr_FR_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_fr_FR_locale<CharT>(cr::tai_time<cr::duration<long long, std::ratio<1, 10>>>{
+ cr::duration<long long, std::ratio<1, 10>>{36611}}) == SV("1958-01-01 01:01:01,1"));
assert(stream_fr_FR_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"));
}
@@ -140,8 +140,8 @@ static void test_ja_JP() {
cr::duration<short, std::ratio<1, 2>>{3600}}) == SV("1958-01-01 00:30:00.0"));
assert(stream_ja_JP_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_ja_JP_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_ja_JP_locale<CharT>(cr::tai_time<cr::duration<long long, std::ratio<1, 10>>>{
+ cr::duration<long long, std::ratio<1, 10>>{36611}}) == SV("1958-01-01 01:01:01.1"));
assert(stream_ja_JP_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"));
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/181560
More information about the libcxx-commits
mailing list