Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e4b86dc
Added UT test cases for baselib datetime_converter dateTimeToEpoch_fa…
Rutuja-Patil-Bosch Mar 24, 2026
d6572d9
Updated the review findings: Removed cout statements
Rutuja-Patil-Bosch Mar 31, 2026
253624a
Merge pull request #1 from bgsw-contrib/bgsw_baselib_ut
Rutuja-Patil-Bosch Apr 1, 2026
3d6f2a0
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 8, 2026
fc37837
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 9, 2026
b89ff46
UT Review finding fix for https://github.com/eclipse-score/baselibs/p…
Rutuja-Patil-Bosch Apr 9, 2026
fa194a0
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 10, 2026
b48fc3c
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 11, 2026
cdb2e30
Follow up fixes for review of PR #135
Rutuja-Patil-Bosch Apr 14, 2026
64ca7b1
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 15, 2026
867860b
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 17, 2026
3318cd3
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 21, 2026
cca3632
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 23, 2026
996ec3a
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 24, 2026
aebe05e
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Apr 30, 2026
996a760
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 1, 2026
38f9f84
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 6, 2026
3df76de
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 7, 2026
df0dd28
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 8, 2026
7355f67
Review findings are fixed for
Rutuja-Patil-Bosch May 8, 2026
b5c9e70
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 9, 2026
85c2f01
Merge pull request #3 from bgsw-contrib/bgsw_baselib_ut_reviewfindingFix
Rutuja-Patil-Bosch May 11, 2026
b5a9f90
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 12, 2026
7751a52
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 14, 2026
1e8c7ba
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 16, 2026
daf8a5f
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 22, 2026
d01dbaa
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 23, 2026
eafda4a
As per review finding updated code. Removed leap year adjustment logi…
Rutuja-Patil-Bosch May 26, 2026
1ea1e9c
Updated code & test case as after 10 years for accuracy to get epoch …
Rutuja-Patil-Bosch May 27, 2026
dfd1566
Follow up PR for https://github.com/eclipse-score/baselibs/pull/135
Rutuja-Patil-Bosch May 28, 2026
0882704
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 29, 2026
f0a726e
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] May 30, 2026
b134f38
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Jun 2, 2026
db12a5f
Merge branch 'eclipse-score:main' into main
bgsw-contrib[bot] Jun 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions score/datetime_converter/datetime_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ namespace score
namespace common
{

std::int8_t daysInMonth(const std::int16_t year, const std::int8_t month)
{
if (month == 2)
{
const bool isLeapYear = (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0)));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can reuse the existing function yearIsLeap() for this.

return isLeapYear ? 29 : 28;
}

if ((month == 4) || (month == 6) || (month == 9) || (month == 11))
{
return 30;
}

return 31;
}

int16_t leapYearsSince1970(const int16_t year)
{
int16_t numOfLeapYears = (((year - 1969) / 4) - ((year - 1901) / 100)) + ((year - 1601) / 400);
Expand Down Expand Up @@ -70,24 +86,7 @@ bool isValidDateTimeFormat(const std::shared_ptr<DateTimeType> dateTime)
return false;
}

if (dateTime->m_month == 2)
{
if (yearIsLeap(dateTime->m_year))
{
return (dateTime->m_day <= 29);
}
else
{
return (dateTime->m_day <= 28);
}
}

if (dateTime->m_month == 4 || dateTime->m_month == 6 || dateTime->m_month == 9 || dateTime->m_month == 11)
{
return (dateTime->m_day <= 30);
}

return true;
return (dateTime->m_day <= daysInMonth(dateTime->m_year, dateTime->m_month));
};

bool dateTimeToEpoch(const std::shared_ptr<DateTimeType> dateTime, time_t* epoch)
Expand Down Expand Up @@ -151,10 +150,6 @@ std::shared_ptr<DateTimeType> epochToDateTime(time_t epoch)
time_t daysSum = (epoch / SECONDS_PER_DAY) + 1;
if (before1970)
{
if (yearIsLeap(dateTime->m_year) && ((daysSum * -1) < DAYS_UNTIL_MONTHS[1]))
{
--daysSum;
}
daysSum = DAYS_PER_YEAR + daysSum - 1;
if (yearIsLeap(dateTime->m_year))
{
Expand Down Expand Up @@ -200,7 +195,7 @@ std::shared_ptr<DateTimeType> epochToDateTime(time_t epoch)
}
else
{
if (daysSum >= DAYS_PER_YEAR)
if (daysSum > DAYS_PER_YEAR)
{
dateTime->m_year = dateTime->m_year + 1;
daysSum = daysSum - DAYS_PER_YEAR;
Expand Down Expand Up @@ -263,6 +258,18 @@ std::shared_ptr<DateTimeType> epochToDateTime(time_t epoch)
dateTime->m_hour = dateTime->m_hour - HOURS_PER_DAY;
dateTime->m_day++;
}

if (dateTime->m_day > daysInMonth(dateTime->m_year, dateTime->m_month))
{
dateTime->m_day = 1;
dateTime->m_month++;

if (dateTime->m_month > 12)
Comment on lines +262 to +267

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (dateTime->m_day > daysInMonth(dateTime->m_year, dateTime->m_month))
{
dateTime->m_day = 1;
dateTime->m_month++;
if (dateTime->m_month > 12)
if (dateTime->m_day == daysInMonth(dateTime->m_year, dateTime->m_month) + 1)
{
dateTime->m_day = 1;
dateTime->m_month++;
if (dateTime->m_month == 13)

{
dateTime->m_month = 1;
dateTime->m_year++;
}
}
}

if (isValidDateTimeFormat(dateTime))
Expand Down
93 changes: 93 additions & 0 deletions score/datetime_converter/datetime_converter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,99 @@ TEST_F(DateTimeConverterTest, test_yearIsLeap)
ASSERT_FALSE(score::common::yearIsLeap(2100));
}

TEST_F(DateTimeConverterTest, invalid_month_values)
{
RecordProperty("Description", "Verify invalid month values are rejected.");
RecordProperty("TestType", "requirements-based");

auto dtt = std::make_shared<DateTimeType>(2020, 0, 10, 3, 4, 5);
ASSERT_FALSE(score::common::isValidDateTimeFormat(dtt));

dtt->m_month = 13;
ASSERT_FALSE(score::common::isValidDateTimeFormat(dtt));

dtt->m_month = -1;
ASSERT_FALSE(score::common::isValidDateTimeFormat(dtt));
}

TEST_F(DateTimeConverterTest, invalid_day_values)
{
RecordProperty("Description", "Verify invalid day values are rejected.");
RecordProperty("TestType", "requirements-based");

auto dtt = std::make_shared<DateTimeType>(2020, 12, 34, 3, 4, 5);
ASSERT_FALSE(score::common::isValidDateTimeFormat(dtt));

dtt->m_day = -1;
ASSERT_FALSE(score::common::isValidDateTimeFormat(dtt));
}

TEST_F(DateTimeConverterTest, dateTimeToEpoch_false_isValidDateTimeFormat)
{
RecordProperty("Description", "Verify dateTimeToEpoch returns false for invalid DateTime input.");
RecordProperty("TestType", "requirements-based");

time_t epoch = static_cast<time_t>(0x7F7F7F7F);

// Invalid: month = 13 -> isValidDateTimeFormat returns false
auto d = std::make_shared<DateTimeType>(2024, 13, 10, 12, 30, 45);

ASSERT_FALSE(score::common::dateTimeToEpoch(d, &epoch));

ASSERT_EQ(epoch, static_cast<time_t>(0x7F7F7F7F));
}

TEST_F(DateTimeConverterTest, EpochToDateTime_Post1970_NonLeapYear_YearRollover)
{
RecordProperty("Description",
"Verify that a post-1970 epoch landing exactly on a non-leap year boundary rolls over to the next year correctly.");
RecordProperty("TestType", "requirements-based");

time_t epoch{};
auto dateTimeOriginal = std::make_shared<DateTimeType>(1971, 1, 1, 0, 0, 0);
ASSERT_TRUE(score::common::dateTimeToEpoch(dateTimeOriginal, &epoch));

auto dateTimeConverted = score::common::epochToDateTime(epoch);
Comment on lines +504 to +508
ASSERT_NE(dateTimeConverted, nullptr);
ASSERT_EQ(dateTimeConverted->m_year, 1971);
ASSERT_EQ(dateTimeConverted->m_month, 1);
ASSERT_EQ(dateTimeConverted->m_day, 1);
ASSERT_EQ(dateTimeConverted->m_hour, 0);
ASSERT_EQ(dateTimeConverted->m_minute, 0);
ASSERT_EQ(dateTimeConverted->m_second, 0);
}

TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_YearBoundary_DayOverflowRollover)
{
RecordProperty("Description",
"Verify that pre-1970 conversion handles day overflow at year boundary by rolling month and year.");
RecordProperty("TestType", "requirements-based");

// 1960-01-01 00:00:00 epoch; this path normalizes an intermediate Dec 32 to Jan 1 of the next year.
const time_t epochAt1960Start = static_cast<time_t>(-315619200);

auto dateTimeConverted = score::common::epochToDateTime(epochAt1960Start);
ASSERT_NE(dateTimeConverted, nullptr);
EXPECT_EQ(dateTimeConverted->m_year, 1960);
EXPECT_EQ(dateTimeConverted->m_month, 1);
EXPECT_EQ(dateTimeConverted->m_day, 1);
EXPECT_EQ(dateTimeConverted->m_hour, 0);
EXPECT_EQ(dateTimeConverted->m_minute, 0);
EXPECT_EQ(dateTimeConverted->m_second, 0);
}

TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1800_ReturnsNull)
{
RecordProperty("Description",
"Verify that epoch values mapping outside supported year range return nullptr.");
RecordProperty("TestType", "requirements-based");

// This epoch maps to year 10000, which is above the supported upper bound (9999).
const time_t epochOutOfRange = static_cast<time_t>(253405000000);

auto dateTimeConverted = score::common::epochToDateTime(epochOutOfRange);
EXPECT_EQ(dateTimeConverted, nullptr);
}
} // namespace testing
} // namespace platform
} // namespace score
Loading