aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
authorMark de Wever <koraq@xs4all.nl>2023-07-10 07:59:58 +0200
committerMark de Wever <koraq@xs4all.nl>2023-07-18 21:17:11 +0200
commitb9f3d241f46c1d2cae42b01e72ef34a18d84c319 (patch)
tree7ba7d04f412fc0b5c2c0a1ab303b9cbed95a3833 /libcxx
parent1be4db73642fa0658d3b1e1dad7ec95259d1d261 (diff)
downloadllvm-b9f3d241f46c1d2cae42b01e72ef34a18d84c319.zip
llvm-b9f3d241f46c1d2cae42b01e72ef34a18d84c319.tar.gz
llvm-b9f3d241f46c1d2cae42b01e72ef34a18d84c319.tar.bz2
[libc++][format] Fixes times before epoch.
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 Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D154865
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/__chrono/convert_to_tm.h2
-rw-r--r--libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp20
-rw-r--r--libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp21
-rw-r--r--libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp20
4 files changed, 62 insertions, 1 deletions
diff --git a/libcxx/include/__chrono/convert_to_tm.h b/libcxx/include/__chrono/convert_to_tm.h
index cc97bfd..1301cd6 100644
--- a/libcxx/include/__chrono/convert_to_tm.h
+++ b/libcxx/include/__chrono/convert_to_tm.h
@@ -78,7 +78,7 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday _
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});
diff --git a/libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp b/libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
index 577ac35..7853f2f 100644
--- a/libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
+++ b/libcxx/test/std/time/time.syn/formatter.file_time.pass.cpp
@@ -49,10 +49,30 @@ static void test_no_chrono_specs() {
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
// Non localized output
+
+ // [time.syn]
+ // using nanoseconds = duration<signed integer type of at least 64 bits, nano>;
+ // using microseconds = duration<signed integer type of at least 55 bits, micro>;
+ // using milliseconds = duration<signed integer type of at least 45 bits, milli>;
+ // using seconds = duration<signed integer type of at least 35 bits>;
+ // using minutes = duration<signed integer type of at least 29 bits, ratio< 60>>;
+ // using hours = duration<signed integer type of at least 23 bits, ratio<3600>>;
+ check(SV("1425-08-04 22:06:56"), SV("{}"), file_seconds(-17'179'869'184s)); // Minimum value for 35 bits.
+ 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)); // Maximum value for 35 bits.
+
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());
diff --git a/libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp b/libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
index 692f41e4..4535a19 100644
--- a/libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
+++ b/libcxx/test/std/time/time.syn/formatter.local_time.pass.cpp
@@ -42,10 +42,31 @@ static void test_no_chrono_specs() {
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
// Non localized output
+
+ // [time.syn]
+ // using nanoseconds = duration<signed integer type of at least 64 bits, nano>;
+ // using microseconds = duration<signed integer type of at least 55 bits, micro>;
+ // using milliseconds = duration<signed integer type of at least 45 bits, milli>;
+ // using seconds = duration<signed integer type of at least 35 bits>;
+ // using minutes = duration<signed integer type of at least 29 bits, ratio< 60>>;
+ // using hours = duration<signed integer type of at least 23 bits, ratio<3600>>;
+ check(
+ SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::local_seconds(-17'179'869'184s)); // Minimum value for 35 bits.
+ 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)); // Maximum value for 35 bits.
+
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());
diff --git a/libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp b/libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
index 1c58fe7..1f1cdcc 100644
--- a/libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
+++ b/libcxx/test/std/time/time.syn/formatter.sys_time.pass.cpp
@@ -42,10 +42,30 @@ static void test_no_chrono_specs() {
std::locale::global(std::locale(LOCALE_fr_FR_UTF_8));
// Non localized output
+
+ // [time.syn]
+ // using nanoseconds = duration<signed integer type of at least 64 bits, nano>;
+ // using microseconds = duration<signed integer type of at least 55 bits, micro>;
+ // using milliseconds = duration<signed integer type of at least 45 bits, milli>;
+ // using seconds = duration<signed integer type of at least 35 bits>;
+ // using minutes = duration<signed integer type of at least 29 bits, ratio< 60>>;
+ // using hours = duration<signed integer type of at least 23 bits, ratio<3600>>;
+ check(SV("1425-08-04 22:06:56"), SV("{}"), std::chrono::sys_seconds(-17'179'869'184s)); // Minimum value for 35 bits.
+ 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)); // Maximum value for 35 bits.
+
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());