I am running a simple program where, I take a time_point
with system_clock::now
then this_thread::sleep_for(seconds(1))
and again a time_point
with system_clock::now
.
Now if I add some extra duration
to the 1st time_point
, it gives exactly the same result for 1 and 2 seconds!
Here is the demo code:
#include<iostream>
#include<chrono>
#include<thread>
using namespace std;
void CheckDuration (std::chrono::duration<int> seconds)
{
auto start = std::chrono::system_clock::now() + seconds;
std::this_thread::sleep_for(std::chrono::seconds(1));
auto stop = std::chrono::system_clock::now();
cout << "Difference = " << std::chrono::duration_cast<std::chrono::seconds>(stop-start).count() << endl;
}
int main ()
{
CheckDuration(std::chrono::duration<int>(0)); // Difference = 1
CheckDuration(std::chrono::duration<int>(1)); // Difference = 0
CheckDuration(std::chrono::duration<int>(2)); // Difference = 0 <=== ???
CheckDuration(std::chrono::duration<int>(3)); // Difference = -1
}
It is clarifying to add output with finer units, for example:
cout << "Difference = " << std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count() << endl;
For me, for the 3rd case (argument 2 seconds), the output is:
Difference = -998
(that is in milliseconds)
To analyze this, let T0
represent the time now()
is first called in CheckDuration
. So:
start == T0 + 2s
stop
is called at T0, plus 1 second for sleeping, plus a tiny bit of processing time we can call epsilon. So:
stop == T0 + 1s + epsilon
Subtracting these two we get:
T0 + 1s + epsilon - (T0 + 2s)
simplifying:
epsilon - 1s
In my case, epsilon == 2ms
duration_cast
has the behavior of truncate towards zero when the conversion can not be made exactly. So -998ms truncates to 0s. For other duration and time point rounding modes which may be helpful in your computations, see:
http://howardhinnant.github.io/duration_io/chrono_util.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With