[libcxx-commits] [PATCH] D154865: [libc++][format] Fixes times before epoch.

Mark de Wever via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jul 10 10:24:42 PDT 2023


Mordante created this revision.
Herald added a project: All.
Mordante requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

The number of days should be rounded down, for both positive and
negative times since epoch. The original code truncated, which is
correct for positive values, but wrong for negative values.

Depends on D138826 <https://reviews.llvm.org/D138826>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154865

Files:
  libcxx/include/__chrono/convert_to_tm.h
  libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
  libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
  libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp


Index: libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
===================================================================
--- libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
+++ libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
@@ -42,10 +42,23 @@
   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
 
   // Non localized output
+
+  check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::sys_seconds(-17'179'869'184s)); // 35 bit minimum
+  check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::sys_seconds(-2'147'483'648s));
+
+  check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::sys_seconds(-24h));
+  check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::sys_seconds(-18h));
+  check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::sys_seconds(-12h));
+  check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::sys_seconds(-6h));
+  check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::sys_seconds(-1s));
+
   check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(0s));
   check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::sys_seconds(946'684'800s));
   check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::sys_seconds(946'688'523s));
 
+  check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::sys_seconds(2'147'483'647s));
+  check(SV("2514-05-30 01:53:03"), SV("{}"), std::chrono::sys_seconds(17'179'869'183s)); // 35 bit maximum
+
   check(SV("2000-01-01 01:02:03.123"), SV("{}"), std::chrono::sys_time<std::chrono::milliseconds>(946'688'523'123ms));
 
   std::locale::global(std::locale::classic());
Index: libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
===================================================================
--- libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
+++ libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
@@ -42,10 +42,23 @@
   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
 
   // Non localized output
+
+  check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::local_seconds(-17'179'869'184s)); // 35 bit minimum
+  check(SV("1901-12-13 20:45:52"), SV("{}"), std::chrono::local_seconds(-2'147'483'648s));
+
+  check(SV("1969-12-31 00:00:00"), SV("{}"), std::chrono::local_seconds(-24h));
+  check(SV("1969-12-31 06:00:00"), SV("{}"), std::chrono::local_seconds(-18h));
+  check(SV("1969-12-31 12:00:00"), SV("{}"), std::chrono::local_seconds(-12h));
+  check(SV("1969-12-31 18:00:00"), SV("{}"), std::chrono::local_seconds(-6h));
+  check(SV("1969-12-31 23:59:59"), SV("{}"), std::chrono::local_seconds(-1s));
+
   check(SV("1970-01-01 00:00:00"), SV("{}"), std::chrono::local_seconds(0s));
   check(SV("2000-01-01 00:00:00"), SV("{}"), std::chrono::local_seconds(946'684'800s));
   check(SV("2000-01-01 01:02:03"), SV("{}"), std::chrono::local_seconds(946'688'523s));
 
+  check(SV("2038-01-19 03:14:07"), SV("{}"), std::chrono::local_seconds(2'147'483'647s));
+  check(SV("2514-05-30 01:53:03"), SV("{}"), std::chrono::local_seconds(17'179'869'183s)); // 35 bit maximum
+
   check(SV("2000-01-01 01:02:03.123"), SV("{}"), std::chrono::local_time<std::chrono::milliseconds>(946'688'523'123ms));
 
   std::locale::global(std::locale::classic());
Index: libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
===================================================================
--- libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
+++ libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
@@ -49,10 +49,23 @@
   std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
 
   // Non localized output
+
+  check(SV("1425-08-04 22:06:56"), SV("{}"), file_seconds(-17'179'869'184s)); // 35 bit minimum
+  check(SV("1901-12-13 20:45:52"), SV("{}"), file_seconds(-2'147'483'648s));
+
+  check(SV("1969-12-31 00:00:00"), SV("{}"), file_seconds(-24h));
+  check(SV("1969-12-31 06:00:00"), SV("{}"), file_seconds(-18h));
+  check(SV("1969-12-31 12:00:00"), SV("{}"), file_seconds(-12h));
+  check(SV("1969-12-31 18:00:00"), SV("{}"), file_seconds(-6h));
+  check(SV("1969-12-31 23:59:59"), SV("{}"), file_seconds(-1s));
+
   check(SV("1970-01-01 00:00:00"), SV("{}"), file_seconds(0s));
   check(SV("2000-01-01 00:00:00"), SV("{}"), file_seconds(946'684'800s));
   check(SV("2000-01-01 01:02:03"), SV("{}"), file_seconds(946'688'523s));
 
+  check(SV("2038-01-19 03:14:07"), SV("{}"), file_seconds(2'147'483'647s));
+  check(SV("2514-05-30 01:53:03"), SV("{}"), file_seconds(17'179'869'183s)); // 35 bit maximum
+
   check(SV("2000-01-01 01:02:03.123"), SV("{}"), file_time<std::chrono::milliseconds>(946'688'523'123ms));
 
   std::locale::global(std::locale::classic());
Index: libcxx/include/__chrono/convert_to_tm.h
===================================================================
--- libcxx/include/__chrono/convert_to_tm.h
+++ libcxx/include/__chrono/convert_to_tm.h
@@ -78,7 +78,7 @@
 
 template <class _Tm, class _Duration>
 _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const chrono::sys_time<_Duration> __tp) {
-  chrono::sys_days __days = chrono::time_point_cast<chrono::days>(__tp);
+  chrono::sys_days __days = chrono::floor<chrono::days>(__tp);
   chrono::year_month_day __ymd{__days};
 
   _Tm __result = std::__convert_to_tm<_Tm>(chrono::year_month_day{__ymd}, chrono::weekday{__days});


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154865.538721.patch
Type: text/x-patch
Size: 5257 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20230710/40eedd4d/attachment.bin>


More information about the libcxx-commits mailing list