Fix chrono.h year_month_weekday_last and year_month_weekday sysdays() (#1396)

* Print test names at test time (#1343)

* Fix chrono.h year_month_weekday_last and year_month_weekday sysdays()

Bug 1: year_month_weekday_last::operator sys_days() — wrong weekday construction

The code was constructing a weekday from a raw day count using weekday(unsigned),
which treats the value as a weekday encoding (0–6). The fix uses weekday(sys_days),
which correctly accounts for the epoch being a Thursday (+4 offset).

Bug 2: year_month_weekday::operator sys_days() — same wrong weekday
construction + off-by-one in day_of_month

Same weekday(unsigned) vs weekday(sys_days) issue. Additionally, the day_of_month
calculation was missing the 1 + base — it computed a 0-based offset from day 1,
but forgot to add the 1 back when converting to an actual day number.

---------

Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com>
Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
Roland Reichwein 2026-04-14 11:48:03 +02:00 committed by GitHub
parent beeb4cf462
commit b14f70698f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 7 deletions

View File

@ -174,11 +174,11 @@ namespace etl
unsigned int target_wd = ymwd.weekday().c_encoding();
unsigned int target_index = ymwd.index();
etl::chrono::weekday first_weekday(static_cast<unsigned>(sd.time_since_epoch().count()));
etl::chrono::weekday first_weekday(sd);
unsigned int first_wd = first_weekday.c_encoding();
unsigned int offset = (target_wd - first_wd + 7U) % 7U;
unsigned int day_of_month = offset + (target_index - 1U) * 7U;
unsigned int day_of_month = 1U + offset + (target_index - 1U) * 7U;
etl::chrono::year_month_day result(year(), month(), etl::chrono::day(day_of_month));
@ -382,7 +382,7 @@ namespace etl
{
etl::chrono::year_month_day ymd(year(), month(), etl::chrono::day(d));
etl::chrono::sys_days ymd_sys_days = static_cast<etl::chrono::sys_days>(ymd);
etl::chrono::weekday wd(static_cast<unsigned>(ymd_sys_days.time_since_epoch().count()));
etl::chrono::weekday wd(ymd_sys_days);
if (wd == weekday())
{

View File

@ -117,10 +117,30 @@ namespace
//*************************************************************************
TEST(test_to_sys_days)
{
Chrono::year_month_weekday ymwd{Chrono::year(2000), Chrono::February, Chrono::weekday_indexed(Chrono::Thursday, 1)};
Chrono::sys_days sd = Chrono::sys_days(ymwd);
// 1st Thursday of February 2000 (Feb 3)
Chrono::year_month_weekday ymwd1{Chrono::year(2000), Chrono::February, Chrono::weekday_indexed(Chrono::Thursday, 1)};
Chrono::sys_days sd1 = Chrono::sys_days(ymwd1);
CHECK_EQUAL(10990, sd1.time_since_epoch().count());
CHECK_EQUAL(10990, sd.time_since_epoch().count());
// 2nd Wednesday of March 2000 (Mar 8)
Chrono::year_month_weekday ymwd2{Chrono::year(2000), Chrono::March, Chrono::weekday_indexed(Chrono::Wednesday, 2)};
Chrono::sys_days sd2 = Chrono::sys_days(ymwd2);
CHECK_EQUAL(11024, sd2.time_since_epoch().count());
// 1st Sunday of January 2000 (Jan 2)
Chrono::year_month_weekday ymwd3{Chrono::year(2000), Chrono::January, Chrono::weekday_indexed(Chrono::Sunday, 1)};
Chrono::sys_days sd3 = Chrono::sys_days(ymwd3);
CHECK_EQUAL(10958, sd3.time_since_epoch().count());
// 3rd Friday of June 1985 (Jun 21)
Chrono::year_month_weekday ymwd4{Chrono::year(1985), Chrono::June, Chrono::weekday_indexed(Chrono::Friday, 3)};
Chrono::sys_days sd4 = Chrono::sys_days(ymwd4);
CHECK_EQUAL(5650, sd4.time_since_epoch().count());
// 2nd Wednesday of March 2024 (Mar 13)
Chrono::year_month_weekday ymwd5{Chrono::year(2024), Chrono::March, Chrono::weekday_indexed(Chrono::Wednesday, 2)};
Chrono::sys_days sd5 = Chrono::sys_days(ymwd5);
CHECK_EQUAL(19795, sd5.time_since_epoch().count());
}
//*************************************************************************

View File

@ -73,7 +73,7 @@ namespace
Chrono::year_month_weekday_last ymwdl{Chrono::year(2000), Chrono::February, Chrono::weekday_last(Chrono::Thursday)};
Chrono::sys_days sd = Chrono::sys_days(ymwdl);
CHECK_EQUAL(11012, sd.time_since_epoch().count());
CHECK_EQUAL(11011, sd.time_since_epoch().count());
}
//*************************************************************************