C++ 11 时间库 chrono

摘要

描述事件通常有我们习惯的描述方式有现在是10点33分,10点33分称为时间点,或者说还有两个小时就到中午饭的时候,两个小时被称为时间段,同时需要记录,比如计算机采用高精度石英作为时钟脉搏,因此一般时间有两种表示方式即时间点或者时间段。
c++11提供了chrono库来表示时间,同时提供时间点 time_point,时间段duration和时钟clock三个类来描述时间,通过使用这三个类可以更加精准的描述时间,时间单位可以精确到你你自己设定的最小单位。
本文将针对这三个类惊醒详细的讲解

时段 duration

时段 指持续时间,比如你做开发,老板问你这个需求要花多久,那么多久就是一个时段,比如一秒,一分钟,一小时,一天等等 c++11 提供duration来描述时段其定义如下

template<class Req, class Period = ratio<1>> class duration;

模板参数
Req: 时段数值类型,比如 1 小时这个 1 是用 int 表示还是 float 或者 double 表示
Period: 时段表示方式,可以理解为参数一的单位,比如参数一 1 小时单位则为小时,默认为 秒
系统已经定义好的单位如下
duration 提供三个构造函数

constexpr duration() = default;                             //默认构造函数
constexpr explicit duration(const _Rep2& _Val)              //给对象赋值一个,段时间的初值
constexpr duration(const duration<_Rep2, _Period2>& _Dur)   //拷贝构造函数

duration对外提供的接口有

方法名 属性 描述
duration:: count() 方法 时间间隔内返回时钟计时周期数
duration:: max() 方法 静态 返回模板参数的最大值Ref
duration:: min() 方法 静态 返回模板参数的最小允许值Ref
duration:: zero() 方法 静态 实际上,返回Rep(0)

duration 重载的运算符

名称 描述
duration:: operator- 返回一份duration对象与求反后的滴答计数。
duration:: operator- 递减存储的时钟周期计数。
duration:: operator = 减少了对指定的值取模存储的滴答计数。
duration:: operator * = 存储的时钟周期数乘以指定的值。
duration:: operator / = 将指定的时钟周期计数存储的滴答计数duration对象。
duration:: operator + 返回 *this。
duration:: operator + + 递增存储的时钟周期数。
duration:: operator + = 添加指定的刻度数duration对象传递给存储的滴答计数。
duration:: operator = 从指定的滴答计数中减去duration存储的滴答计数中的对象。

标准库预定义如下时间单位

typedef ratio<1, 1000000000> nano;
typedef ratio<1, 1000000> micro;
typedef ratio<1, 1000> milli;
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;          //小时

各个时段之间相互转化,提供了 duration_cast 运算符其定义如下

1 template <class ToDuration, class Rep, class Period>
2   constexpr ToDuration duration_cast (const duration<Rep,Period>& dtn);

一个使用的例子

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


typedef duration<int, ratio<60>> mySecond;

int main()
{

    //1. 静态方法
    cout <<"mySecond::max() : "<<mySecond::max().count() << endl;   //返回mySecond最大的count数目
    cout <<"mySecond::min() : "<<mySecond::min().count() << endl;   //返回mysecond最小的count的数目
    cout <<"mySecond::zero(): " <<mySecond::zero().count() << endl; //返回当对mySecond赋值为0的时候起count数是多少

    //2. 构造函数
    mySecond d1(20);                                        //20分钟
    duration<unsigned int, ratio<24 * 60 * 60>>  d2(5);     //1天
    duration<float, ratio<24 * 60 * 60>> d3 = d2 + d1;      //1天 + 20 分钟结果用天表示,注意如果需要用小数点 req参数请使用float或者double
    cout << d3.count() << endl;

    //3. duration_cast的使用
    cout << duration_cast<seconds>(d1).count() << endl;     //20分钟转化成秒
    cout << duration_cast<hours>(d2).count() << endl;       //将一天转化成小时

    return 0;
}

时点 time_point

时点表示一个时间中的一个点,时间点 ,即是一个瞬时,很短暂的,比如说 12点。这是时间点,就是在钟表指向12点的那一刻。存储相对于纪元(epoch)的duration,time_point总是与一个特定的clock(下一部分详细讲解)相关联。 chrome库时间点类定义如下

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

模板参数:
Clock: 与之相关联的时钟,下一节详细讲解,本节使用sytem_clock
Duration: 用于描述时间点的时钟周期最小单位,默认为微妙

构造函数:

constexpr time_point();                                          //缺省构造函数

constexpr explicit time_point(const duration& Dur);             //用一个时间段对他进行赋值

template <class Duration2>  
constexpr time_point(const time_point<clock, Duration2>& Tp);   //暂时理解为拷贝构造函数

对外接口

名称 描述
time_point:: max 方法 指定的上限值time_point::ref。
time_point:: min 方法 指定的下限time_point::ref。
time_point:: time_since_epoch 方法 返回存储的duration值。
time_point:: operator + = 将指定的值添加到存储持续时间。
time_point:: operator = 从中减去指定的值的存储持续时间。

用例

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

typedef duration<int, ratio<20 * 60 * 60>> day_t;

int main()
{

    time_point<system_clock> tp2(system_clock::now());
    cout <<"从纪元到现在经过"<<duration_cast<day_t>(tp2.time_since_epoch()).count() <<"天"<<endl;

    day_t oneday(1);
    decltype(tp2) tomarrow = tp2 + oneday;

    hours h = duration_cast<hours>(tomarrow - tp2);
    cout <<"一天"<<h.count() <<"小时"<<endl;


    return 0;
}

时钟

C++11为我们提供了三种时钟类型:system_clock、steady_clock、high_resolution_clock。 这三个时间类都提供了rep、period、duration成员类型。因为各个系统能提供的时间精度可能不同,所以period的真正类型是implementation-defined的。这三个时钟类都提供了一个静态成员函数now()用于获取当前时间,该函数的返回值是一个time_point类型,后面会介绍。
注意:,虽然这三个时钟都很多相同的成员类型和成员函数,但它们是没有亲缘关系的。这三个时钟类型都是类,并非模板类。
这三个时钟有什么区别呢?system_clock就类似Windows系统右下角那个时钟,是系统时间。明显那个时钟是可以乱设置的。明明是早上10点,却可以设置成下午3点。steady_clock则针对system_clock可以随意设置这个缺陷而提出来的,他表示时钟是不能设置的。high_resolution_clock则是一个高分辨率时钟。

#include <iostream>
#include <chrono>
#include <string>
#include <ctime>
using namespace std;
using namespace chrono;

#pragma warning(disable:4996)

typedef duration<int, ratio<20 * 60 * 60>> day_t;

int main()
{
    system_clock::time_point now = system_clock::now();

    time_t now_tm = system_clock::to_time_t(now);

    string now_time = ctime(&now_tm);

    cout <<"now : "<<now_time << endl;

    day_t oneday(1);

    auto tomorrow = now + oneday;
    auto tom_tm = system_clock::to_time_t(tomorrow);
    string tom_time = ctime(&tom_tm);

    cout << "tomorrow : " << tom_time << endl;


    return 0;
}

猜你喜欢

转载自blog.csdn.net/timeinsist/article/details/80460594