Current UTC time point in C++

Viewed 4149

I want to send a time point over a network connection to detect the ping time and for other calculations. The time has to have millisecond precision, but using:

auto currently = std::chrono::time_point_cast<std::chrono::milliseconds>(
    std::chrono::system_clock::now()
);

... returns (of course) the system time which is of course not UTC. Is there any way to calculate the UTC value without transforming the time_point to a time_t and then back again? I read something about std::chrono::utc_clock, but even with C++20 I can not find the definition in the <chrono> header.

Edit

This would be a working solution, but it is an awful solution, because it is very inefficient... There must be something better:

auto currently = std::chrono::time_point_cast<std::chrono::milliseconds>(
    std::chrono::system_clock::now()
);
time_t time = std::chrono::system_clock::to_time_t(currently);
struct tm *tm = gmtime(&time);
// Create a new time_point from struct tm that is in UTC now
1 Answers

std::chrono::utc_clock exists in the C++20 standard but neither clang nor GCC have implemented it in their standard libraries yet. This is quite common for the latest language standard. Not all features are implemented by all compilers yet.

However, since C++20, std::chrono::system_clock has a specified epoch, namely 1970-01-01 00:00.000 UTC, which is the same as the implied epoch of std::time_t:

system_clock measures Unix Time (i.e., time since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, not counting leap seconds).

Note that std::time_t doesn't have any specified epoch, it is just usually 1970-01-01 00:00.000 UTC:

Although not defined, this is almost always an integral value holding the number of seconds (not counting leap seconds) since 00:00, Jan 1 1970 UTC, corresponding to POSIX time

So what you need to do is:

std::chrono::time_point currently = std::chrono::time_point_cast<std::chrono::milliseconds>(
    std::chrono::system_clock::now()
);
std::chrono::duration millis_since_utc_epoch = currently.time_since_epoch();

// use millis_since_utc_epoch.count() to get the milliseconds as an integer
Related