在Visual Studio 2017中使用high_resolution_clock来获取错误的日期和时间/从历元时间获取毫秒数(1970年1月1日)

时间:2019-02-03 14:34:13

标签: c++ visual-studio c++11 time

我对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的输出是:

  
    

1970年1月6日星期二07:28:21

  

MinGW输出:

  
    

2019年2月3日星期日18:01:38

  

有什么办法可以修复代码,使其在所有编译器中正常工作?我需要high_resolution_clock才能访问毫秒。

2 个答案:

答案 0 :(得分:2)

high_resolution_clock是具有最高可配置性的时钟的别名:

  

std :: chrono :: high_resolution_clock类表示实现所提供的最小滴答周期的时钟。它可以是std :: chrono :: system_clock或std :: chrono :: steady_clock或第三独立时钟的别名。

这可以解释您使用不同编译器的不同时间。

steady_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年以来的时间,而只能返回自时钟纪元以来的时间,这在大多数情况下是您想要的行为。

答案 1 :(得分:1)

代码假定time_since_epoch()返回自1970年1月1日以来的秒数,因此该值可以分配给变量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"
}

更新

获取自1970年1月1日以来的毫秒数:

#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的时代始于1970年1月1日。