I am testing a library like follows:
std::chrono::system_clock::time_point FromDateTime(const DateTime& dateTime)
{
std::tm tm{};
tm.tm_year = dateTime.Year - 1900;
tm.tm_mon = dateTime.Month - 1;
tm.tm_mday = dateTime.Day;
tm.tm_hour = dateTime.Hour;
tm.tm_min = dateTime.Minute;
tm.tm_sec = dateTime.Second;
const auto& time = std::mktime(&tm);
const auto& timePoint = std::chrono::system_clock::from_time_t(time);
return timePoint;
}
TEST_F(MyLibraryFixture, GetDateTime)
{
// Arrange
const auto& now = std::chrono::system_clock::now();
// Act
const auto& actual = _testee->GetDateTime();
// Assert
const auto& timeDiscrepanceInSec = std::chrono::duration_cast<std::chrono::seconds>(FromDateTime(actual) - now);
ASSERT_TRUE(timeDiscrepanceInSec.count() < 10);
}
The DateTime type is just a raw struct with the above used fields. The call
_testee->GetDateTime();
gives a DateTime struct back and the date time is actually local time. For some reason inherent to the library I am testing, I need to compare the local time with the time it is now. My code above seems to be working fine, I "hope" it will still work when we get back to Summer time.
Now, c++20 exposes a lot of date time utilities. I have browsed the documentation, I have tried some stuff, but I was not able to come up with a reliable counterpart to the above snippet. Is it any possible (I mean, without using std::mktime and the strange std::tm)?
The closest I was able to come is this, but it is still wrong (I get a discrepancy of one hour):
std::chrono::time_point<std::chrono::local_t, std::chrono::seconds> FromDateTime(const DateTime& dateTime)
{
const auto& d = std::chrono::year_month_day(std::chrono::year(dateTime.Year), std::chrono::month(dateTime.Month), std::chrono::day(dateTime.Day));
const auto& t = std::chrono::hours(dateTime.Hour) + std::chrono::minutes(dateTime.Minute) + std::chrono::seconds(dateTime.Second);
const auto& dt = std::chrono::local_days(d) + t;
return dt;
}
TEST_F(MyLibraryFixture, GetDateTime)
{
// Arrange
const auto& now = std::chrono::utc_clock::now();
// Act
const auto& actual = _testee->GetDateTime();
// Assert
const auto& timeDiscrepanceInSec = std::chrono::duration_cast<std::chrono::seconds>(FromDateTime(actual).time_since_epoch() - now.time_since_epoch());
ASSERT_TRUE(timeDiscrepanceInSec.count() < 10);
}