C++11 chrono解析
chrono 是C++11的时间库,提供了计时、时钟等功能。
学习chrono, 关键是理解里面时间段(Durations)、时间点(Time points)的概念。
精度
时钟节拍(时间精度):
template<intmax_t N, intmax_t D = l> class ratio;
其中:N表示分子,D表示分母,默认用秒表示的时间单位。
N对应于其成员num,D对应于其成员den
常用的单位:
1 | ratio<60, 1> minute |
ratio主要是为后面将要讲解的时间段,时间点等提供精度(单位)
1 |
|
时间段:
1 | template<class Rep, class Period = ratio<l> > |
std::chrono::duration 表示一段时间,比如两个小时,12.88秒,半个时辰,一炷香的时间等等。
Rep表示一种数值类型,用来表示Period的数量,比如int float double。
Period是ratio类型,用来表示上面所说的单位精度,比如second millisecond。
chrono中宏定义了许多特例了的duration:
就是常见的hours,minutes,seconds,milliseconds等,使用std::chrono::milliseconds直接使用。
(1)构造函数很简单
1 | (1) duration() = default; // 默认构造 |
(2) 成员函数count() 返回单位时间的数量。
1 |
|
(3) 当不要截断值的情况下(时转换成秒是没问题,但是秒转换成时就不行)时间段的转换是隐式的。显示转换可以由 std::chrono::duration_cast<>
来完成。
比如 std::chrono::milliseconds ms(54802);
std::chrono::seconds s = std::chrono::duration_caststd::chrono::seconds(ms);
这里的结果就是截断的,而不是进行了舍入,所以s最后的值将为54。
时间点:
1 | template<class Clock, class Duration = typename Clock::duration> |
std::chrono::time_point 表示一个具体时间,如上个世纪80年代、今天下午3点、火车出发时间等,只要它能用计算机时钟表示。
第一个模板参数Clock用来指定所要使用的时钟(标准库中有三种时钟,system_clock,steady_clock和high_resolution_clock。见 时钟详解 ),第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration<>
)
时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。
(1)构造函数
1 | time_point(); // 默认构造函数,时间戳作为其值 |
(2) 时间点有个重要的函数:duration time_since_epoch()
(用于获取当前时间点距离时间戳的时间长度)
即经常用来得到当前时间点到1970年1月1日00:00的时间距离、该函数返回的duration的精度和构造time_point的时钟(Clock)有关(见 时钟详解)。
1 |
|
时钟(代表当前系统的时间)
chrono中有三种时钟:system_clock
, steady_clock
和hight_resolution_clock
。 每一个clock类中都有确定的time_point,duration,Rep,Period类型。
system_clock是不稳定。因为时钟是可调的,即这种是完全自动适应本地账户的调节。这种调节可能造成的是,首次调用now()返回的时间要早于上次调用now()所返回的时间,这就违反了节拍频率的均匀分布。稳定闹钟对于超时的计算很重要,所以C++标准库提供了一个稳定时钟 std::chrono::steady_clock
。
std::chrono::hight_resolution_clock
是标准库中提供的具有最小节拍周期(因此具有最高的精度的时钟)。
上文所说time_since_epoch()
,以及将要介绍的now()函数的返回值都依赖于时钟的精度,测试时钟的精度的一种方式就是:
1 |
|
windows系统的测试结果是system_clock
的精度是100纳秒,而hight_resolution
的精度是1纳秒,对于程序来说,一般毫秒级就够了,所以说chrono提供的时钟精度绰绰有余。
(1)成员函数static time_point now() noexcept;
用于获取系统的当前时间。
(2)由于各种time_point
表示方式不同,chrono也提供了相应的转换函数 time_point_cast
。
1 | template<class ToDuration, class Clock, class Duration> |
(3)其他成员函数:
1 | to_time_t() time_point转换成time_t秒 |
综合应用:
输出当前时间,并计算当前的时间距离1970年1月1日00:00的毫秒数。
1 |
|
将上面的程序中millisconds换成microseconds或者更小的单位,便可达到微妙,甚至更高的精度。