Получить неправильные дату и время с помощью high_resolution_clock в Visual Studio 2017 / Получить количество миллисекунд от времени эпохи (1 января 1970 г.) - PullRequest
0 голосов
/ 03 февраля 2019

У меня проблема с Visual Studio 2017.

Я пытаюсь получить текущее время и дату с разрешением в миллисекундах.Я попробовал следующий код в нескольких компиляторах:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
#include <chrono>
using namespace std;
using namespace chrono;

int main()
{

    high_resolution_clock::time_point p = high_resolution_clock::now();
    milliseconds ms = duration_cast<milliseconds>(p.time_since_epoch());
    seconds s = duration_cast<seconds>(ms);
    time_t t = s.count();
    cout << ctime(&t) << "\n";
    cin.ignore(1);
}

Каждый компилятор, кроме Visual Studio 2017, печатает правильное время.Выходные данные Visual Studio:

Вт 6 января 07:28:21 1970

Выход MinGW:

Вс 3 февраля 18:01:38 2019

Есть ли способ исправить код, чтобы он корректно работал во всех компиляторах?Мне нужен high_resolution_clock, чтобы получить доступ к миллисекундам.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

high_resolution_clock - это псевдоним для часов с наибольшим доступным разрешением:

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

Это может объяснить разное время, которое вы получаете на разных компиляторах.

stable_clock Не гарантирует, что даст время, которое имеет смысл, но хорошо для сохранениявремя отслеживания:

Эти часы не связаны со временем настенных часов (например, это может быть время с момента последней перезагрузки) и наиболее подходят для измерения интервалов.Есть ли способ исправить код, чтобы он корректно работал во всех компиляторах?Мне нужен high_resolution_clock, чтобы получить доступ к миллисекундам.

system_clock представляет часы вашей ОС:

Класс std :: chrono :: system_clock представляетобщесистемные настенные часы реального времени.

Возможно, они не монотонны: в большинстве систем системное время можно отрегулировать в любой момент.Это единственные часы C ++, которые могут отображать свои временные точки на время в стиле C и, следовательно, отображаться (до C ++ 20).

Если вам нужны миллисекунды даты или времени, используйте std :: chrono :: system_clock, но если вам просто нужно отслеживать пройденное время, используйте std :: chrono :: high_resolution_clock.

Чтобы получить количество миллисекунд с момента запуска system_clock:

auto timePoint = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>
                                    (timePoint.time_since_epoch());
std::cout << "since epoch: " << ms.count() << " ms";

над фрагментом кода должно работать в большинстве операционных систем и компиляторов, хотя не гарантируется, что time_since_epoch вернет время с 1970 года, нотолько для возврата времени с эпохи часов, что в большинстве случаев является вашим желаемым поведением.

0 голосов
/ 03 февраля 2019

Код предполагает, что time_since_epoch() возвращает количество секунд с 1 января 1970 года, поэтому значение можно присвоить переменной time_t.

. Это предположение неверно.time_since_epoch() может вернуть любую единицу.На самом деле, high_resolution_clock не предназначен для получения абсолютного времени и даты.Он предназначен для измерения производительности в диапазоне микросекунд и нано секунд.

Чтобы получить абсолютное время / дату, используйте system_clock.Класс имеет статический метод для создания значения time_t:

#include <iostream>
#include <chrono>
#include <ctime>

using namespace std;
using namespace chrono;

int main()
{
    time_point<system_clock> now = system_clock::now();
    time_t now_time = system_clock::to_time_t(now);
    cout << ctime(&now_time) << "\n"
}

Обновление

Чтобы получить миллисекунды с 1 января 1970 года:

#include <iostream>
#include <chrono>
#include <ctime>

using namespace std;
using namespace chrono;

int main()
{
    system_clock::time_point epochStart = system_clock::from_time_t(0);
    long long epochStartMs = duration_cast<milliseconds>(epochStart.time_since_epoch()).count();

    system_clock::time_point timePoint = system_clock::now();
    long long timePointMs = duration_cast<milliseconds>(timePoint.time_since_epoch()).count();

    long long durMs = timePointMs - epochStartMs;

    cout << "Since 1st Jan 1970: " << durMs << " ms" << "\n";
}

Для большинства систем epochStartMs, вероятно, будет 0. Но я думаю, что стандарт не гарантирует, что у system_clock будет начало эпохи 1 января 1970 года.

...