c++qtc++-chronoqdatetime

C++ current timestamp - QDateTime vs chrono::system_clock


Qt's currentMSecsSinceEpoch seems to differ from chrono::system_clock::now(). Even if I call currentMSecsSinceEpoch after system_clock::now() the timestamp returned by Qt is sometimes smaller than the stl timestamp. Why is this happening?

Code:

#include <iostream>
#include <chrono>
#include <QtCore>
int main()
{
    namespace sc = std::chrono;

    for (int j = 0; j < 10; ++j)
    {
        const auto stl_now = sc::system_clock::now();
        std::this_thread::sleep_for(sc::microseconds{1});
        const auto qt_now = QDateTime::currentMSecsSinceEpoch();

        const auto duration_since_epoch = stl_now.time_since_epoch();

        std::cout << '\n';
        std::cout << "1. Chrono now:           " << duration_since_epoch.count() << '\n';
        std::cout << "1. Chrono now (floored): " << sc::floor<sc::milliseconds>(duration_since_epoch).count() << '\n';
        std::cout << "2. Qt now:               " << qt_now << '\n';
    }
}

Output:

1. Chrono now:           17012623315247298
1. Chrono now (floored): 1701262331524
2. Qt now:               1701262331524
 
1. Chrono now:           17012623315265318
1. Chrono now (floored): 1701262331526
2. Qt now:               1701262331526
 
1. Chrono now:           17012623315279808
1. Chrono now (floored): 1701262331527
2. Qt now:               1701262331527
 
1. Chrono now:           17012623315296035
1. Chrono now (floored): 1701262331529
2. Qt now:               1701262331529
 
1. Chrono now:           17012623315314812
1. Chrono now (floored): 1701262331531
2. Qt now:               1701262331531
 
1. Chrono now:           17012623315332218
1. Chrono now (floored): 1701262331533
2. Qt now:               1701262331532
 
1. Chrono now:           17012623315347844
1. Chrono now (floored): 1701262331534
2. Qt now:               1701262331534
 
1. Chrono now:           17012623315362278
1. Chrono now (floored): 1701262331536
2. Qt now:               1701262331535
 
1. Chrono now:           17012623315378605
1. Chrono now (floored): 1701262331537
2. Qt now:               1701262331537
 
1. Chrono now:           17012623315393145
1. Chrono now (floored): 1701262331539
2. Qt now:               1701262331539

Solution

  • Using Windows:

    Qt calls GetSystemTime whereas chrono uses GetSystemTimePreciseAsFileTime. GetSystemTime has a resolution / precision of milliseconds as shown here. GetSystemTimePreciseAsFileTime uses the highest precision possible which is <1µs, as stated here.

    The unexpected behaviour could be explained by the fact that under the hood two different system calls are used to get the wall clock time.