diff --git a/score/datetime_converter/datetime_converter_test.cpp b/score/datetime_converter/datetime_converter_test.cpp index 9ea21212b..b5c66e81c 100644 --- a/score/datetime_converter/datetime_converter_test.cpp +++ b/score/datetime_converter/datetime_converter_test.cpp @@ -453,6 +453,122 @@ 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", "Negative"); + RecordProperty("Requirement", "DatetimeValidation"); + RecordProperty("Coverage", "MonthValidation"); + + auto dtt = std::make_shared(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", "Negative"); + RecordProperty("Requirement", "DatetimeValidation"); + RecordProperty("Coverage", "DayValidation"); + + auto dtt = std::make_shared(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", "Negative"); + RecordProperty("Requirement", "DatetimeValidation"); + RecordProperty("Coverage", "ErrorHandling"); + + time_t epoch = static_cast(0x7F7F7F7F); + + // Invalid: month = 13 -> isValidDateTimeFormat returns false + auto d = std::make_shared(2024, 13, 10, 12, 30, 45); + + ASSERT_FALSE(score::common::dateTimeToEpoch(d, &epoch)); + + ASSERT_EQ(epoch, static_cast(0x7F7F7F7F)); +} + +TEST_F(DateTimeConverterTest, EpochToDateTime_Pre1970_LeapYear_DaysSumDecrementedInJanuary) +{ + RecordProperty("Description", "Verify pre-1970 leap year round-trip stability."); + RecordProperty("TestType", "Boundary"); + RecordProperty("Requirement", "DatetimeConversion_Pre1970_LeapYear"); + RecordProperty("Coverage", "LeapYearHandling_RoundTrip"); + + for (int month = 1; month <= 12; ++month) + { + for (int day = 1; day <= 31; ++day) + { + if ((month == 2 && day > 29) || + (month == 4 && day > 30) || + (month == 6 && day > 30) || + (month == 9 && day > 30) || + (month == 11 && day > 30)) + continue; + + time_t epoch{}; + auto d = std::make_shared(1968, month, day, 0, 0, 1); + + if (!score::common::dateTimeToEpoch(d, &epoch)) + continue; + + auto dt = score::common::epochToDateTime(epoch); + if (dt == nullptr) + continue; + time_t epoch_roundtrip = static_cast(-1); + ASSERT_TRUE(score::common::dateTimeToEpoch(dt, &epoch_roundtrip)); + } + } +} + +TEST_F(DateTimeConverterTest, EpochToDateTime_Post1970_LeapYear_DaysSumDecremented) +{ + RecordProperty("Description", + "Sweep across 1972 leap year (post-1970) to verify leap adjustment and round-trip stability."); + RecordProperty("TestType", "Boundary"); + RecordProperty("Requirement", "DatetimeConversion_Post1970_LeapYear"); + RecordProperty("Coverage", "LeapYearHandling_RoundTrip"); + + for (int month = 1; month <= 12; ++month) + { + for (int day = 1; day <= 31; ++day) + { + if ((month == 2 && day > 29) || + (month == 4 && day > 30) || + (month == 6 && day > 30) || + (month == 9 && day > 30) || + (month == 11 && day > 30)) + continue; + + time_t epoch{}; + auto d = std::make_shared(1972, month, day, 0, 0, 1); + + if (!score::common::dateTimeToEpoch(d, &epoch)) + continue; + + auto dt = score::common::epochToDateTime(epoch); + ASSERT_NE(dt, nullptr); + + time_t epoch_roundtrip = static_cast(-1); + ASSERT_TRUE(score::common::dateTimeToEpoch(dt, &epoch_roundtrip)); + } + + } +} + } // namespace testing } // namespace platform } // namespace score