C++ Chrono – Convert high_resolution_clock::time_point to time_t with VC141

c++c++-chronostd

In Visual Studio 2013 I just used

#include <chrono>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <sstream>

std::string Time_Point_String(const std::chrono::high_resolution_clock::time_point & timePoint)
{
    time_t timeNow = std::chrono::system_clock::to_time_t(timePoint);

    tm time = *localtime(&timeNow);

    std::stringstream timeString;
timeString << std::setfill('0') << 1900 + time.tm_year << "-" << std::setw(2) << time.tm_mon + 1 << "-" << std::setw(2) << time.tm_mday << " " << std::setw(2) << time.tm_hour << ":" << std::setw(2) << time.tm_min << ":" << std::setw(2) << time.tm_sec;

    return timeString.str();
}

int main()
{
    const std::chrono::high_resolution_clock::time_point & timePoint = std::chrono::high_resolution_clock::now();

    std::cout << Time_Point_String(timePoint);
    return 0;
}

But with Visual Studio 2017 I get a compiler error:

Error C2664 '__time64_t std::chrono::system_clock::to_time_t(const std::chrono::system_clock::time_point &) noexcept': cannot convert argument 1 from 'const std::chrono::steady_clock::time_point' to 'const std::chrono::system_clock::time_point &'

So it isn't possible anymore to convert a high_resolution_clock::time_point to a different time_point like system_clock::time_point and there is no possibility to convert high_resolution_clock::time_point to time_t directly?

How can I handle this situation?
Is it possible at all (some SO postings say they are just completely different clocks and conversion doesn't make sense)?
As far as I've seen, the function did what I expected it to do in Visual Studio 2013 application, it has provided the right local time for a high_resolution time_point.

Best Answer

This comes from the fact that std::chrono::high_resolution_clock is a type alias for std::chrono::system_clock or std::chrono::steady_clock:

Class std::chrono::high_resolution_clock represents the clock with the smallest tick period provided by the implementation. It may be an alias of std::chrono::system_clock or std::chrono::steady_clock, or a third, independent clock.

This means std::chrono::high_resolution_clock::time_point can be a type alias for std::chrono::system_clock::time_point, or it can be an other type. From your question, one can guess it does for MSVC2013, making your code valid, but is not for MSVC2017, making your code invalid.

As a conclusion, the following code might or might not be valid, in an unspecified manner (it depends on the compiler and its target architecture):

std::chrono::high_resolution_clock::time_point timePoint = /* something */;
std::chrono::system_clock::to_time_t(timePoint);
Related Question