#include <chrono>
int main()
{
using clock = std::chrono::system_clock;
using time_point = std::chrono::time_point<clock>;
auto tp_now = clock::now();
auto tp_min = time_point::min();
bool b1 = tp_now > tp_min;
bool b2 = (tp_now - tp_min) > std::chrono::seconds{ 0 };
cout << boolalpha << b1 << endl << b2 << endl;
}
The expected output is:
true
true
But the actual output is:
true
false
Why does std::chrono::time_point
not behave as expected?
With:
using clock = std::chrono::system_clock;
using time_point = std::chrono::time_point<clock>;
time_point
is implemented as if it stores a value of type Duration indicating the time interval from the start of the Clock's epoch. (See std::chrono::time_point
)
The duration
member type of clock
(and of time_point
) is capable of representing negative durations.
Thus duration
in your implementation may be implemented with a back-end signed integer, (it can be implemented with unsigned integer but with a complicated comparison).
In that particular implementation,
time_point::min();
time_point t(clock::duration::min());
time_point t(clock::duration(std::numeric_limits<Rep>::lowest()));
and tp_now
is greater than zero
, thus when you subtract them, you get an integer overflow because the result is larger than std::numeric_limits<Rep>::max()
. In implementation with signed back-end, it's undefined behavior, in implementation with unsigned back-end, I don't know about it, but I guess its special comparison will make its false
.
In this example, tp_min
is -9223372036854775808
ticks from its epoch, that number is the same with std::numeric_limits<duration::rep>::lowest()
TL;DR; It's integer overflow. Don't use
(tp1 - tp2) > std::chrono::duration<whatever_rep>::zero
Instead, use
tp1 > tp2