I'm fiddling around with time representation in C++.
I would like to have a strictly monotonic representation of time, that handles leap seconds well. The utc_clock in C++20 should be able to do that, and since my compiler doesn't support this version yet, I'm using HowardHinnant/date.
To understand the library better I have started making small test cases, but got stuck on one. I take two dates, before and after insertion of a leap second and check that duration between those two dates actually has the extra second.
This is the test case:
TEST(DateTime, TimeLeap)
{
using namespace std::chrono;
using namespace date;
// Two dates with a leap second in between
// https://en.wikipedia.org/wiki/Leap_second
auto t1 = clock_cast<utc_clock>(static_cast<sys_days>(2016_y/December/31));
auto t2 = clock_cast<utc_clock>(static_cast<sys_days>(2017_y/January/1));
EXPECT_EQ(duration_cast<seconds>(t2 - t1).count(), 24 * 3600 + 1);
}
but it fails for me:
common/tests/datetime.cpp:39: Failure
Expected: duration_cast<seconds>(t2 - t1).count()
Which is: 86400
To be equal to: 24 * 3600 + 1
Which is: 86401
It seems that the conversion between sys_clock and utc_clock doesn't add the leap second.
Suspecting that the problem is the resolution of sys_days, I've also tried doing a time_point_cast<seconds>(...) before the clock_cast<utc_clock>, but the result didn't change.
I've also tried using 2017-01-02 as the second date, in case there was an issue with distinction between 2016-12-31 23:59:60 and 2017-01-01 00:00 -- the leap second also didn't appear there.