繁体   English   中英

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

[英]Get wrong date and time with high_resolution_clock in Visual Studio 2017 / Get number of milliseconds from epoch time (1 jan 1970)

我有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输出:

Sun Feb 03 18:01:38 2019

有没有办法修复代码,以便它在所有编译器中正常工作? 我需要high_resolution_clock来访问毫秒。

high_resolution_clock是具有最高resoultion可用的时钟的别名:

类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年以来的时间,但只返回自时钟时代以来的时间,这在大多数情况下是您期望的行为。

该代码假定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日开始了它的纪元。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM