From 46ee000c21d364a7c178d106cd93c741845152ee Mon Sep 17 00:00:00 2001 From: statementreply Date: Wed, 10 Feb 2021 00:00:11 +0800 Subject: [PATCH 1/4] Add test for calendar date conversion --- .../test.cpp | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp index 90d6d7ad946..4617ecece53 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp @@ -700,6 +700,134 @@ constexpr void year_month_day_test() { } } } + + if (is_constant_evaluated()) { + // clang-format off + static_assert(sys_days{ 2000y/ 1/ 1} == sys_days{days{ 10957}}); + static_assert(sys_days{ 2000y/ 1/31} == sys_days{days{ 10987}}); + static_assert(sys_days{ 2000y/ 2/ 1} == sys_days{days{ 10988}}); + static_assert(sys_days{ 2000y/ 2/29} == sys_days{days{ 11016}}); + static_assert(sys_days{ 2000y/ 3/ 1} == sys_days{days{ 11017}}); + static_assert(sys_days{ 2000y/ 3/31} == sys_days{days{ 11047}}); + static_assert(sys_days{ 2000y/ 4/ 1} == sys_days{days{ 11048}}); + static_assert(sys_days{ 2000y/ 4/30} == sys_days{days{ 11077}}); + static_assert(sys_days{ 2000y/ 5/ 1} == sys_days{days{ 11078}}); + static_assert(sys_days{ 2000y/ 5/31} == sys_days{days{ 11108}}); + static_assert(sys_days{ 2000y/ 6/ 1} == sys_days{days{ 11109}}); + static_assert(sys_days{ 2000y/ 6/30} == sys_days{days{ 11138}}); + static_assert(sys_days{ 2000y/ 7/ 1} == sys_days{days{ 11139}}); + static_assert(sys_days{ 2000y/ 7/31} == sys_days{days{ 11169}}); + static_assert(sys_days{ 2000y/ 8/ 1} == sys_days{days{ 11170}}); + static_assert(sys_days{ 2000y/ 8/31} == sys_days{days{ 11200}}); + static_assert(sys_days{ 2000y/ 9/ 1} == sys_days{days{ 11201}}); + static_assert(sys_days{ 2000y/ 9/30} == sys_days{days{ 11230}}); + static_assert(sys_days{ 2000y/10/ 1} == sys_days{days{ 11231}}); + static_assert(sys_days{ 2000y/10/31} == sys_days{days{ 11261}}); + static_assert(sys_days{ 2000y/11/ 1} == sys_days{days{ 11262}}); + static_assert(sys_days{ 2000y/11/30} == sys_days{days{ 11291}}); + static_assert(sys_days{ 2000y/12/ 1} == sys_days{days{ 11292}}); + static_assert(sys_days{ 2000y/12/31} == sys_days{days{ 11322}}); + static_assert(sys_days{ -400y/ 2/29} == sys_days{days{ -865566}}); + static_assert(sys_days{ -400y/ 3/ 1} == sys_days{days{ -865565}}); + static_assert(sys_days{ -1y/ 2/28} == sys_days{days{ -719835}}); + static_assert(sys_days{ -1y/ 3/ 1} == sys_days{days{ -719834}}); + static_assert(sys_days{ -1y/12/31} == sys_days{days{ -719529}}); + static_assert(sys_days{ 0y/ 1/ 1} == sys_days{days{ -719528}}); + static_assert(sys_days{ 0y/ 2/29} == sys_days{days{ -719469}}); + static_assert(sys_days{ 0y/ 3/ 1} == sys_days{days{ -719468}}); + static_assert(sys_days{ 1900y/ 3/ 1} == sys_days{days{ -25508}}); + static_assert(sys_days{ 1901y/ 2/28} == sys_days{days{ -25144}}); + static_assert(sys_days{ 1903y/ 3/ 1} == sys_days{days{ -24413}}); + static_assert(sys_days{ 1904y/ 2/29} == sys_days{days{ -24048}}); + static_assert(sys_days{ 1996y/ 3/ 1} == sys_days{days{ 9556}}); + static_assert(sys_days{ 1997y/ 2/28} == sys_days{days{ 9920}}); + static_assert(sys_days{ 1999y/ 3/ 1} == sys_days{days{ 10651}}); + static_assert(sys_days{ 2000y/ 2/29} == sys_days{days{ 11016}}); + static_assert(sys_days{ 2000y/ 3/ 1} == sys_days{days{ 11017}}); + static_assert(sys_days{ 2001y/ 2/28} == sys_days{days{ 11381}}); + static_assert(sys_days{ 2003y/ 3/ 1} == sys_days{days{ 12112}}); + static_assert(sys_days{ 2004y/ 2/29} == sys_days{days{ 12477}}); + static_assert(sys_days{ 2096y/ 3/ 1} == sys_days{days{ 46081}}); + static_assert(sys_days{ 2097y/ 2/28} == sys_days{days{ 46445}}); + static_assert(sys_days{ 2099y/ 3/ 1} == sys_days{days{ 47176}}); + static_assert(sys_days{ 2100y/ 2/28} == sys_days{days{ 47540}}); + static_assert(sys_days{-32767y/ 1/ 1} == sys_days{days{-12687428}}); + static_assert(sys_days{ 32767y/12/31} == sys_days{days{ 11248737}}); + + static_assert( 2000y/ 1/ 1 == year_month_day{sys_days{days{ 10957}}}); + static_assert( 2000y/ 1/31 == year_month_day{sys_days{days{ 10987}}}); + static_assert( 2000y/ 2/ 1 == year_month_day{sys_days{days{ 10988}}}); + static_assert( 2000y/ 2/29 == year_month_day{sys_days{days{ 11016}}}); + static_assert( 2000y/ 3/ 1 == year_month_day{sys_days{days{ 11017}}}); + static_assert( 2000y/ 3/31 == year_month_day{sys_days{days{ 11047}}}); + static_assert( 2000y/ 4/ 1 == year_month_day{sys_days{days{ 11048}}}); + static_assert( 2000y/ 4/30 == year_month_day{sys_days{days{ 11077}}}); + static_assert( 2000y/ 5/ 1 == year_month_day{sys_days{days{ 11078}}}); + static_assert( 2000y/ 5/31 == year_month_day{sys_days{days{ 11108}}}); + static_assert( 2000y/ 6/ 1 == year_month_day{sys_days{days{ 11109}}}); + static_assert( 2000y/ 6/30 == year_month_day{sys_days{days{ 11138}}}); + static_assert( 2000y/ 7/ 1 == year_month_day{sys_days{days{ 11139}}}); + static_assert( 2000y/ 7/31 == year_month_day{sys_days{days{ 11169}}}); + static_assert( 2000y/ 8/ 1 == year_month_day{sys_days{days{ 11170}}}); + static_assert( 2000y/ 8/31 == year_month_day{sys_days{days{ 11200}}}); + static_assert( 2000y/ 9/ 1 == year_month_day{sys_days{days{ 11201}}}); + static_assert( 2000y/ 9/30 == year_month_day{sys_days{days{ 11230}}}); + static_assert( 2000y/10/ 1 == year_month_day{sys_days{days{ 11231}}}); + static_assert( 2000y/10/31 == year_month_day{sys_days{days{ 11261}}}); + static_assert( 2000y/11/ 1 == year_month_day{sys_days{days{ 11262}}}); + static_assert( 2000y/11/30 == year_month_day{sys_days{days{ 11291}}}); + static_assert( 2000y/12/ 1 == year_month_day{sys_days{days{ 11292}}}); + static_assert( 2000y/12/31 == year_month_day{sys_days{days{ 11322}}}); + static_assert( -400y/ 2/29 == year_month_day{sys_days{days{ -865566}}}); + static_assert( -400y/ 3/ 1 == year_month_day{sys_days{days{ -865565}}}); + static_assert( -1y/ 2/28 == year_month_day{sys_days{days{ -719835}}}); + static_assert( -1y/ 3/ 1 == year_month_day{sys_days{days{ -719834}}}); + static_assert( -1y/12/31 == year_month_day{sys_days{days{ -719529}}}); + static_assert( 0y/ 1/ 1 == year_month_day{sys_days{days{ -719528}}}); + static_assert( 0y/ 2/29 == year_month_day{sys_days{days{ -719469}}}); + static_assert( 0y/ 3/ 1 == year_month_day{sys_days{days{ -719468}}}); + static_assert( 1900y/ 3/ 1 == year_month_day{sys_days{days{ -25508}}}); + static_assert( 1901y/ 2/28 == year_month_day{sys_days{days{ -25144}}}); + static_assert( 1903y/ 3/ 1 == year_month_day{sys_days{days{ -24413}}}); + static_assert( 1904y/ 2/29 == year_month_day{sys_days{days{ -24048}}}); + static_assert( 1996y/ 3/ 1 == year_month_day{sys_days{days{ 9556}}}); + static_assert( 1997y/ 2/28 == year_month_day{sys_days{days{ 9920}}}); + static_assert( 1999y/ 3/ 1 == year_month_day{sys_days{days{ 10651}}}); + static_assert( 2000y/ 2/29 == year_month_day{sys_days{days{ 11016}}}); + static_assert( 2000y/ 3/ 1 == year_month_day{sys_days{days{ 11017}}}); + static_assert( 2001y/ 2/28 == year_month_day{sys_days{days{ 11381}}}); + static_assert( 2003y/ 3/ 1 == year_month_day{sys_days{days{ 12112}}}); + static_assert( 2004y/ 2/29 == year_month_day{sys_days{days{ 12477}}}); + static_assert( 2096y/ 3/ 1 == year_month_day{sys_days{days{ 46081}}}); + static_assert( 2097y/ 2/28 == year_month_day{sys_days{days{ 46445}}}); + static_assert( 2099y/ 3/ 1 == year_month_day{sys_days{days{ 47176}}}); + static_assert( 2100y/ 2/28 == year_month_day{sys_days{days{ 47540}}}); + static_assert(-32767y/ 1/ 1 == year_month_day{sys_days{days{-12687428}}}); + static_assert( 32767y/12/31 == year_month_day{sys_days{days{ 11248737}}}); + // clang-format on + } else { + sys_days sys2{year{y_min} / 1 / 1}; + + for (int iy = y_min; iy <= y_max; ++iy) { + const year y{iy}; + + for (auto um = 1u; um <= 12u; ++um) { + const month m{um}; + + const year_month_day ymd_first = y / m / 1; + assert(sys_days{ymd_first} == sys2); + assert(year_month_day{sys2} == ymd_first); + + const year_month_day ymd_last = y / m / last; + sys2 += (ymd_last.day() - 1d); + + assert(sys_days{ymd_last} == sys2); + assert(year_month_day{sys2} == ymd_last); + + sys2 += days{1}; + } + } + } } constexpr void year_month_day_last_test() { From 17ef59cd911fd500709970a1d3ef4508c1ae1b27 Mon Sep 17 00:00:00 2001 From: statementreply Date: Wed, 10 Feb 2021 00:06:42 +0800 Subject: [PATCH 2/4] Optimize calendar date conversion --- stl/inc/chrono | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index 7927b883277..ad6b2ebb85a 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -1394,35 +1394,32 @@ namespace chrono { // courtesy of Howard Hinnant // https://howardhinnant.github.io/date_algorithms.html#civil_from_days _NODISCARD static constexpr year_month_day _Civil_from_days(int _Tp) noexcept { - static_assert(numeric_limits::digits >= 18); - static_assert(numeric_limits::digits >= 20); - const int _Zx = _Tp + 719468; // Shift epoch to 0000-03-01 - const int _Era = (_Zx >= 0 ? _Zx : _Zx - 146096) / 146097; - const unsigned int _Day_of_era = static_cast(_Zx - _Era * 146097); // [0, 146096] - const unsigned int _Year_of_era = - (_Day_of_era - _Day_of_era / 1460 + _Day_of_era / 36524 - _Day_of_era / 146096) / 365; // [0, 399] - const int _Year = static_cast(_Year_of_era) + _Era * 400; // Where March is the first month - const unsigned int _Day_of_year = - _Day_of_era - (365 * _Year_of_era + _Year_of_era / 4 - _Year_of_era / 100); // [0, 365] - const unsigned int _Mp = (5 * _Day_of_year + 2) / 153; // [0, 11] - const unsigned int _Day = _Day_of_year - (153 * _Mp + 2) / 5 + 1; // [1, 31] - const unsigned int _Month = _Mp + (_Mp < 10 ? 3 : static_cast(-9)); // [1, 12] + static_assert(numeric_limits::digits >= 32); + static_assert(numeric_limits::digits >= 26); + const int _Zx = _Tp + 719468; // Shift epoch to 0000-03-01 + const int _Century = (_Zx >= 0 ? 4 * _Zx + 3 : 4 * _Zx - 146093) / 146097; + const unsigned int _Day_of_century = + static_cast(_Zx - ((146097 * _Century) >> 2)); // [0, 36524] + const unsigned int _Year_of_century = (91867 * (_Day_of_century + 1)) >> 25; // [0, 99] + const int _Year = static_cast(_Year_of_century) + _Century * 100; // Where March is the first month + const unsigned int _Day_of_year = _Day_of_century - ((1461 * _Year_of_century) >> 2); // [0, 365] + const unsigned int _Mp = (535 * _Day_of_year + 333) >> 14; // [0, 11] + const unsigned int _Day = _Day_of_year - ((979 * _Mp + 19) >> 5) + 1; // [1, 31] + const unsigned int _Month = _Mp + (_Mp < 10 ? 3 : static_cast(-9)); // [1, 12] return year_month_day{_CHRONO year{_Year + (_Month <= 2)}, _CHRONO month{_Month}, _CHRONO day{_Day}}; } // courtesy of Howard Hinnant // https://howardhinnant.github.io/date_algorithms.html#days_from_civil _NODISCARD constexpr days _Days_from_civil() const noexcept { static_assert(numeric_limits::digits >= 18); - static_assert(numeric_limits::digits >= 20); - const int _Ye = static_cast(_Year) - (_Month <= _CHRONO month{2}); - const unsigned int _Mo = static_cast(_Month); - const int _Era = (_Ye >= 0 ? _Ye : _Ye - 399) / 400; - const unsigned int _Year_of_era = static_cast(_Ye - _Era * 400); // [0, 399] - const unsigned int _Day_of_year = (153 * (_Mo + (_Mo > 2 ? static_cast(-3) : 9)) + 2) / 5 - + static_cast(_Day) - 1; // [0, 365] - const unsigned int _Day_of_era = - _Year_of_era * 365 + _Year_of_era / 4 - _Year_of_era / 100 + _Day_of_year; // [0, 146096] - return days{_Era * 146097 + static_cast(_Day_of_era) - 719468}; + static_assert(numeric_limits::digits >= 26); + const unsigned int _Mo = static_cast(_Month); + const int _Ye = static_cast(_Year) - (_Mo <= 2); + const int _Century = (_Ye >= 0 ? _Ye : _Ye - 99) / 100; + const unsigned int _Year_of_century = static_cast(_Ye - _Century * 100); // [0, 99] + const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] + const unsigned int _Day_of_year = ((979 * _Mp + 19) >> 5) + static_cast(_Day) - 1; // [0, 365] + return days{((_Ye * 1461) >> 2) - _Century + (_Century >> 2) + static_cast(_Day_of_year) - 719468}; } }; From e3a97d2489419153ca727973fedb539d5b5e1940 Mon Sep 17 00:00:00 2001 From: statementreply Date: Wed, 10 Feb 2021 00:39:36 +0800 Subject: [PATCH 3/4] Remove unused variable --- stl/inc/chrono | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index ad6b2ebb85a..f0ed30a944f 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -1413,11 +1413,10 @@ namespace chrono { _NODISCARD constexpr days _Days_from_civil() const noexcept { static_assert(numeric_limits::digits >= 18); static_assert(numeric_limits::digits >= 26); - const unsigned int _Mo = static_cast(_Month); - const int _Ye = static_cast(_Year) - (_Mo <= 2); - const int _Century = (_Ye >= 0 ? _Ye : _Ye - 99) / 100; - const unsigned int _Year_of_century = static_cast(_Ye - _Century * 100); // [0, 99] - const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] + const unsigned int _Mo = static_cast(_Month); + const int _Ye = static_cast(_Year) - (_Mo <= 2); + const int _Century = (_Ye >= 0 ? _Ye : _Ye - 99) / 100; + const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] const unsigned int _Day_of_year = ((979 * _Mp + 19) >> 5) + static_cast(_Day) - 1; // [0, 365] return days{((_Ye * 1461) >> 2) - _Century + (_Century >> 2) + static_cast(_Day_of_year) - 719468}; } From 3b22218969c1c7e64c926b8f680306e82ffdbe7d Mon Sep 17 00:00:00 2001 From: statementreply Date: Thu, 11 Feb 2021 13:35:58 +0800 Subject: [PATCH 4/4] Add tests for `!ok() && y_.ok() && m_.ok()` case [time.cal.ymd.members]/19: Returns: If `ok()`, [...]. Otherwise, if `y_.ok() && m_.ok()` is `true`, returns `sys_days{y_/m_/1d} + (d_ - 1d). Otherwise [...] Removed incorrect comment on the range of `_Day_of_year`, and changed its type from `unsigned int` to `int` to clarify that it could be negative. Added test cases for this clause. --- stl/inc/chrono | 12 ++-- .../test.cpp | 58 ++++++++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/stl/inc/chrono b/stl/inc/chrono index f0ed30a944f..25d3b2ac196 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -1413,12 +1413,12 @@ namespace chrono { _NODISCARD constexpr days _Days_from_civil() const noexcept { static_assert(numeric_limits::digits >= 18); static_assert(numeric_limits::digits >= 26); - const unsigned int _Mo = static_cast(_Month); - const int _Ye = static_cast(_Year) - (_Mo <= 2); - const int _Century = (_Ye >= 0 ? _Ye : _Ye - 99) / 100; - const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] - const unsigned int _Day_of_year = ((979 * _Mp + 19) >> 5) + static_cast(_Day) - 1; // [0, 365] - return days{((_Ye * 1461) >> 2) - _Century + (_Century >> 2) + static_cast(_Day_of_year) - 719468}; + const unsigned int _Mo = static_cast(_Month); // [1, 12] + const int _Ye = static_cast(_Year) - (_Mo <= 2); + const int _Century = (_Ye >= 0 ? _Ye : _Ye - 99) / 100; + const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] + const int _Day_of_year = static_cast(((979 * _Mp + 19) >> 5) + static_cast(_Day)) - 1; + return days{((_Ye * 1461) >> 2) - _Century + (_Century >> 2) + _Day_of_year - 719468}; } }; diff --git a/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp b/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp index 4617ecece53..4bb31c8a863 100644 --- a/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp +++ b/tests/std/tests/P0355R7_calendars_and_time_zones_dates/test.cpp @@ -804,6 +804,57 @@ constexpr void year_month_day_test() { static_assert( 2100y/ 2/28 == year_month_day{sys_days{days{ 47540}}}); static_assert(-32767y/ 1/ 1 == year_month_day{sys_days{days{-12687428}}}); static_assert( 32767y/12/31 == year_month_day{sys_days{days{ 11248737}}}); + + static_assert(sys_days{ 2000y/ 1/ 0} == sys_days{days{ 10956}}); + static_assert(sys_days{ 2000y/ 1/255} == sys_days{days{ 11211}}); + static_assert(sys_days{ 2000y/ 2/ 0} == sys_days{days{ 10987}}); + static_assert(sys_days{ 2000y/ 2/255} == sys_days{days{ 11242}}); + static_assert(sys_days{ 2000y/ 3/ 0} == sys_days{days{ 11016}}); + static_assert(sys_days{ 2000y/ 3/255} == sys_days{days{ 11271}}); + static_assert(sys_days{ 2000y/ 4/ 0} == sys_days{days{ 11047}}); + static_assert(sys_days{ 2000y/ 4/255} == sys_days{days{ 11302}}); + static_assert(sys_days{ 2000y/ 5/ 0} == sys_days{days{ 11077}}); + static_assert(sys_days{ 2000y/ 5/255} == sys_days{days{ 11332}}); + static_assert(sys_days{ 2000y/ 6/ 0} == sys_days{days{ 11108}}); + static_assert(sys_days{ 2000y/ 6/255} == sys_days{days{ 11363}}); + static_assert(sys_days{ 2000y/ 7/ 0} == sys_days{days{ 11138}}); + static_assert(sys_days{ 2000y/ 7/255} == sys_days{days{ 11393}}); + static_assert(sys_days{ 2000y/ 8/ 0} == sys_days{days{ 11169}}); + static_assert(sys_days{ 2000y/ 8/255} == sys_days{days{ 11424}}); + static_assert(sys_days{ 2000y/ 9/ 0} == sys_days{days{ 11200}}); + static_assert(sys_days{ 2000y/ 9/255} == sys_days{days{ 11455}}); + static_assert(sys_days{ 2000y/10/ 0} == sys_days{days{ 11230}}); + static_assert(sys_days{ 2000y/10/255} == sys_days{days{ 11485}}); + static_assert(sys_days{ 2000y/11/ 0} == sys_days{days{ 11261}}); + static_assert(sys_days{ 2000y/11/255} == sys_days{days{ 11516}}); + static_assert(sys_days{ 2000y/12/ 0} == sys_days{days{ 11291}}); + static_assert(sys_days{ 2000y/12/255} == sys_days{days{ 11546}}); + static_assert(sys_days{ -400y/ 2/255} == sys_days{days{ -865340}}); + static_assert(sys_days{ -400y/ 3/ 0} == sys_days{days{ -865566}}); + static_assert(sys_days{ -1y/ 2/255} == sys_days{days{ -719608}}); + static_assert(sys_days{ -1y/ 3/ 0} == sys_days{days{ -719835}}); + static_assert(sys_days{ -1y/12/255} == sys_days{days{ -719305}}); + static_assert(sys_days{ 0y/ 1/ 0} == sys_days{days{ -719529}}); + static_assert(sys_days{ 0y/ 2/255} == sys_days{days{ -719243}}); + static_assert(sys_days{ 0y/ 3/ 0} == sys_days{days{ -719469}}); + static_assert(sys_days{ 1900y/ 3/ 0} == sys_days{days{ -25509}}); + static_assert(sys_days{ 1901y/ 2/255} == sys_days{days{ -24917}}); + static_assert(sys_days{ 1903y/ 3/ 0} == sys_days{days{ -24414}}); + static_assert(sys_days{ 1904y/ 2/255} == sys_days{days{ -23822}}); + static_assert(sys_days{ 1996y/ 3/ 0} == sys_days{days{ 9555}}); + static_assert(sys_days{ 1997y/ 2/255} == sys_days{days{ 10147}}); + static_assert(sys_days{ 1999y/ 3/ 0} == sys_days{days{ 10650}}); + static_assert(sys_days{ 2000y/ 2/255} == sys_days{days{ 11242}}); + static_assert(sys_days{ 2000y/ 3/ 0} == sys_days{days{ 11016}}); + static_assert(sys_days{ 2001y/ 2/255} == sys_days{days{ 11608}}); + static_assert(sys_days{ 2003y/ 3/ 0} == sys_days{days{ 12111}}); + static_assert(sys_days{ 2004y/ 2/255} == sys_days{days{ 12703}}); + static_assert(sys_days{ 2096y/ 3/ 0} == sys_days{days{ 46080}}); + static_assert(sys_days{ 2097y/ 2/255} == sys_days{days{ 46672}}); + static_assert(sys_days{ 2099y/ 3/ 0} == sys_days{days{ 47175}}); + static_assert(sys_days{ 2100y/ 2/255} == sys_days{days{ 47767}}); + static_assert(sys_days{-32767y/ 1/ 0} == sys_days{days{-12687429}}); + static_assert(sys_days{ 32767y/12/255} == sys_days{days{ 11248961}}); // clang-format on } else { sys_days sys2{year{y_min} / 1 / 1}; @@ -818,9 +869,14 @@ constexpr void year_month_day_test() { assert(sys_days{ymd_first} == sys2); assert(year_month_day{sys2} == ymd_first); + const year_month_day ymd_min = y / m / 0; + assert(sys_days{ymd_min} == sys2 - days{1}); + + const year_month_day ymd_max = y / m / 255; + assert(sys_days{ymd_max} == sys2 + days{254}); + const year_month_day ymd_last = y / m / last; sys2 += (ymd_last.day() - 1d); - assert(sys_days{ymd_last} == sys2); assert(year_month_day{sys2} == ymd_last);