Search code examples
c++macosqtc++14c++-chrono

How to get the real calendar microseconds time (epoch since 1970) in Mac OSX?


Kindly go through below Qn for the context:
Why does clang++/g++ not giving correct microseconds output for chrono::high_resolution_clock::now() in Mac OSX?

As already discussed in above thread, I intend to get microseconds time since 1970.
Now using chrono::high_resolution_clock::now().time_since_epoch() works well in popular platforms except OSX & possibly iOS. In [our] Mac systems, the microseconds time is generated since the system restart & not since 1970.

Is there any portable [or Mac specific] way to get the time since 1970, with the precision of microseconds?
Solution specific to Qt are also welcome.


Solution

  • On macOS this is how you can get microseconds since 1970-01-01 UTC (excluding leap seconds):

    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        std::cout << std::chrono::system_clock::now().time_since_epoch().count() << "us\n";
    }
    

    This just output for me:

    1503715928742714us
    

    This isn't quite portable. Though all platform's system_clocks do measure time since 1970-01-01 UTC (not specified but de facto standard), they do so with differing precisions. Only macOS uses microseconds. To portably output microseconds:

    using namespace std::chrono;
    std::cout << time_point_cast<microseconds>(system_clock::now()).time_since_epoch().count() << "us\n";
    

    If you would like to do this operation while exploring what precision other platforms measure this time with, you can use Howard Hinnant's date/time library to very easily do this:

    #include "date.h"
    #include <chrono>
    #include <iostream>
    
    int
    main()
    {
        using namespace date;
        using namespace std::chrono;
        std::cout << system_clock::now().time_since_epoch() << '\n';
    }
    

    For me this just output:

    1503716308206361µs
    

    On gcc platforms the units would be ns. And on Windows the units would be [1/10000000]s, which is 1/10 of a µs or 100ns.


    About chrono::high_resolution_clock:

    The standard specifies that high_resolution_clock may be a type alias for system_clock or steady_clock, or it may be a separate type. On macOS and Windows, high_resolution_clock is a typedef for steady_clock. On gcc high_resolution_clock is a typedef for system_clock. So you can't depend on the type or behavior of high_resolution_clock. I don't recommend its use.


    About chrono::steady_clock:

    steady_clock is like a stopwatch. It is great for timing how long something takes. But it can't tell you the time of day. It has no relationship whatsoever to a human calendar on any platform. On macOS steady_clock it is a count of nanoseconds since the computer booted.

    For a video tutorial about the current different std::chrono clocks, please see https://www.youtube.com/watch?v=P32hvk8b13M


    Only system_clock counts time since the Unix epoch (de facto standard, not official). There is a proposal under consideration to make this official, and to add these additional clocks:

    utc_clock: Like system_clock but includes leap seconds.

    tai_clock: Measures physical seconds since 1958-01-01 00:00:00. Moves a second ahead of utc_clock every time there is a leap second. All minutes have 60 seconds.

    gps_clock: Like tai_clock but measures time since the first Sunday of January 1980 00:00:00 UTC.

    file_clock: This is proposed to be the clock that the C++17 filesystem library is based on. It isn't specified, but all known implementations relate this somehow to the civil calendar.