《深入应用C++11》笔记-时间相关工具chrono,duration、time_point、clock

chrono是一个模版库,包含了一系列时间相关功能。

 

duration

 

std::chrono::duration 和字面意思一样,表示一段时间,原型是一个模板类:

 

 

 

template<
    class Rep,
    class Period = std::ratio<1>
> class duration;1234

 

Rep表示一种数值类型,用来表示Period的数量,比如int、float。
Period是ratio类型,代表用秒表示的时间单位,默认为std::ratio<1> ,std::ratio代表一个分数,如下代码,N是分子,D是分母。

 

 

 

template <intmax_t N, intmax_t D = 1> struct ratio;1

 

Period是std::ratio<1>时,说明分数为1/1,也就是1秒。

 

在chrono中预定义了一系列的duration:

 

 

 

typedef duration<long long, nano> nanoseconds;
typedef duration<long long, micro> microseconds;
typedef duration<long long, milli> milliseconds;
typedef duration<long long> seconds;
typedef duration<int, ratio<60> > minutes;
typedef duration<int, ratio<3600> > hours;123456

 

以seconds为例,Period为std::ratio<1>代表1s,std::chrono::seconds(10)就代表10秒。
以minutes为例,Period为std::ratio<60>代表60s,std::chrono::minutes(10)就代表10分钟。
以milliseconds为例,Period为milli(typedef ratio<1, 1000>)代表1/1000s,std::chrono::minutes(10)就代表10毫秒。

 

duration对象常用于std::this_thread::sleep_for、std::timed_mutex::try_lock_for等函数,作为入参:

 

 

 

std::this_thread::sleep_for(std::chrono::seconds(10));  // 等待10s1

 

另外,C++11还提供了duration之间的类型转换duration_cast,用于不同时间精度间的装换:

 

 

 

#include <iostream>
#include <chrono>

 

int main()
{
    std::chrono::seconds scd(10);
    std::cout << scd.count() << std::endl;   // 10
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(scd).count() << std::endl;     // 10000

 

    return 0;
}

 

// 精度高转换成精度低的时候会导致精度丢失,需要注意
#include <iostream>
#include <chrono>

 

int main()
{
    std::chrono::milliseconds scd(10001);
    std::cout << scd.count() << std::endl;      // 10001
    std::cout << std::chrono::duration_cast<std::chrono::seconds>(scd).count() << std::endl;                     // 10

 

    return 0;
}
12345678910111213141516171819202122232425

 

time_point

 

std::chrono::time_point用于表示一个时间点,需要为时间点指定参考时钟(clock,clock类需要满足指定要求,详见https://zh.cppreference.com/w/cpp/named_req/Clock)和相对于参考时钟步进值。它被实现成如同存储一个 Duration 类型的自 Clock 的纪元起始开始的时间间隔的值。

 

 

 

template
<class Clock, class Duration = typename Clock::duration>
class time_point;123

 

例如以下代码,其中system_clock::time_point被定义为time_point,system_clock是C++11实现的clock类(一般是从格林威治标准时间开始),此处作为time_point模板的第一个类型,第二个类型Clock::duration被定义为microseconds,也就是说time_point表示从格林威治标准时间(1970-01-01 00:00:00.000)开始到指定时间的毫秒数。

 

 

 

#include <iostream>
#include <chrono>
using namespace std::chrono;

 

int main()
{
    system_clock::time_point now = system_clock::now();  // now表示当前时间到格林威治标准时间的毫秒数
    //等效于time_point<system_clock> now = system_clock::now();

 

    std::cout << now.time_since_epoch().count() << std::endl;  // 1534602834436896
    return 0;
}123456789101112

 

time_point对象常用于std::this_thread::sleep_until、std::timed_mutex::try_lock_until等函数,作为入参:

 

 

 

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;

 

int main()
{
    system_clock::time_point until = system_clock::now();
    until += seconds(5);
    std::this_thread::sleep_until(until);   // 一直等待到当前时间加上5s之后的时间点

 

    return 0;
}12345678910111213

 

同样,time_point也支持精度装换time_point_cast:

 

 

 

#include <iostream>
#include <chrono>
using namespace std::chrono;

 

int main()
{
    time_point<system_clock> now = system_clock::now();
    std::cout << now.time_since_epoch().count() << std::endl;  // 毫秒级

 

    time_point<system_clock, hours> hour_now =
        time_point_cast<hours>(system_clock::now());
    std::cout << hour_now.time_since_epoch().count() << std::endl;   // 小时级

 

    return 0;
}123456789101112131415

 

clock

 

C++11新增了时钟的概念,时钟 (Clock) 概念描述由 std::chrono::duration 、 std::chrono::time_point 和获取当前 time_point 的函数 now() 组成的一束内容,将时钟的 time_point 原点定为时钟的纪元。C++11中有三种时钟:system_clock,steady_clock和high_resolution_clock。

 

system_clock表示本地系统的时钟,因此是不稳定的,因为有可能被修改,上文已经举例了一些它的用法,下面再列举一个常用的显示当前系统时间的用法:

 

 

 

#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
using namespace std::chrono;

 

int main()
{
    time_point<system_clock> now = system_clock::now();
    time_t t_now = system_clock::to_time_t(now);
    tm* tm_now = std::localtime(&t_now);
    std::cout << std::put_time(tm_now, "%Y-%m-%d %H:%M:%S") << std::endl;

 

    return 0;
}123456789101112131415

 

steady_clock表示稳定的时间间隔,后一次调用now()得到的时间总是比前一次的值大(如果中途修改了系统时间,也不影响now()的结果),所以通常用来计算时间间隔:

 

 

 

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;

 

int main()
{
    time_point<steady_clock> begin_time = steady_clock::now();
    std::this_thread::sleep_for(milliseconds(10));
    time_point<steady_clock> end_time = steady_clock::now();

 

    // steady_clock的精度为纳秒,装换成毫秒输出
    std::cout << duration_cast<milliseconds>(end_time - begin_time).count() << std::endl;

 

    getchar();
    return 0;
}1234567891011121314151617

 

high_resolution_clock 表示实现提供的拥有最小计次周期的时钟,它可以是system_clock或steady_clock的别名,或第三个独立时钟。在我的实验的机器中被定义为:

typedef steady_clock high_resolution_clock;
---------------------
作者:WizardtoH
原文:https://blog.****.net/WizardtoH/article/details/81738682
 

上一篇:C++中头文件简介(stdio.h & chrono)


下一篇:chrono使用