Конвертировать high_resolution_clock :: time_point в time_t с помощью VC141 - PullRequest
0 голосов
/ 12 сентября 2018

В Visual Studio 2013 я только что использовал

#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;
}

Но в Visual Studio 2017 я получаю ошибку компилятора:

Ошибка C2664 '__time64_t std :: chrono :: system_clock:: to_time_t (const std :: chrono :: system_clock :: time_point &) noexcept ': невозможно преобразовать аргумент 1 из' const std :: chrono :: stable_clock :: time_point 'в' const std :: chrono :: system_clock ::time_point & '

Так что больше невозможно преобразовать high_resolution_clock::time_point в другой time_point, такой как system_clock::time_point, и нет возможности напрямую преобразовать high_resolution_clock::time_point в time_t?

Как я могу справиться с этой ситуацией?Возможно ли это вообще (некоторые сообщения SO говорят, что это просто совершенно разные часы, и конверсия не имеет смысла)?Насколько я видел, функция сделала то, что ожидала, в приложении Visual Studio 2013, она предоставила правильное местное время для точки времени high_resolution.

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Вы можете конвертировать только между time_point s с тех же часов. std::chrono::high_resolution_clock - псевдоним для других часов. Если это std::chrono::system_clock, вы можете преобразовать в time_t.

Если std::chrono::high_resolution_clock - это другие часы, вы можете приблизительно преобразовать их в std::chrono::system_clock, взяв разницу между текущим временем и временем ввода в std::chrono::high_resolution_clock и добавив эту разницу к системному времени:

#include <iostream>
#include <chrono>

int main()
{
  auto input = std::chrono::high_resolution_clock::now();

  auto highResNow = std::chrono::high_resolution_clock::now();
  auto systemNow = std::chrono::system_clock::now();
  auto output = systemNow + (highResNow - input);
  std::cout << std::chrono::system_clock::to_time_t( output ) << "\n";
}

Обратите внимание, что преобразование только приблизительное, в идеале highResNow и systemNow необходимо рассчитывать одновременно, но между ними будет небольшой разрыв. Преобразование также будет более ненадежным, чем дальше от времени ввода и текущего времени.

0 голосов
/ 12 сентября 2018

Это связано с тем, что std::chrono::high_resolution_clock является псевдонимом типа для std::chrono::system_clock или std::chrono::steady_clock:

Класс std::chrono::high_resolution_clock представляет часы с наименьшим периодом такта, предоставленным реализацией. Это может быть псевдоним std::chrono::system_clock или std::chrono::steady_clock или третьи независимые часы.

Это означает, что std::chrono::high_resolution_clock::time_point может быть псевдонимом типа для std::chrono::system_clock::time_point или другим типом. Исходя из вашего вопроса, можно предположить, что он подходит для MSVC2013, делая ваш код действительным, но не для MSVC2017, делая ваш код недействительным.

В заключение, следующий код может быть, а может и не быть допустимым, неопределенным образом (это зависит от компилятора и его целевой архитектуры):

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