摘要
描述事件通常有我们习惯的描述方式有现在是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;
}