【C++标准库】std::chrono,
编程语言最该拥有. 最不可或缺的程序库,应该是用来处理日期和时间的程序库。然而经验显示,这样 的程序库远比想象中难设计。问题出在它应该提供多少弹性和多少精度。事实上,在过去, C和POSIX提供的 系统时间(system time)接口,允许从秒转换做亳秒(millisecond) , 再至微秒(microsecond), 最终至纳秒(nanosecond), 问题是每次转换就需要一个新接口。基于这个原因,C++11开始提供一个精度中立(precision-neutral)的程序库,它常被称为chrono程序库, 为它的特性被定义于。
此外C++标准库也提供一个基本的C和POSIX接口,用来处理日历时间。你也可以使用自C++11的thread的程序库。等待某个线程或程序(主线程)一 段时间。
引入几个概念:
- duration(时间段)
- timepoint(时间点)
- tick(片刻数)
- epoch(起点,重要纪元)
- clock(时钟)
解释一下:
– duration(时间段) = tick(片刻数)* (分,秒,毫秒,1/3秒)时间单位,如3分钟 = 3个* 1分钟,或者2个*1.5分钟;所以这个时间单位,并不是规定好的 。
– timepoint(时间点) = epoch(起始点) + duration(时间段)。2000年新年午夜(timepoint) =1970年1月1日(epoch)+ 1262300400秒(duration)
– epoch(时间点),不同的clock(时钟)有不同的epoch(起点)。一般而言,处理两个timepoint之间的差距时,必须采用相同的epoch/clock。
0.ratio精度
时钟节拍(时间精度):
template <intmax_t N, intmax_t D = 1> class ratio;
其中N表示分子,D表示分母,默认用秒表示的时间单位。
N对应于其成员num,D对应于其成员den
这里有一个模板类ratio<num ,den >,作用就是一个时间单位。(可以是0.5秒,1.5秒的非整数)
ratio<60, 1> minute
ratio<1, 1> second
ratio<1, 1000> microsecond
1.Duration
1.1先看怎么用duration构建时间段对象。
std::chrono::duration<int> twentySeconds(20);
std::chrono::duration<double, std::ratio<60>> halfAMinute (0.5);
std::chrono::duration<long,std::ratio<l,1000>>oneMillisecond(l);
duration模板有两个template参数,第一个(tick)片刻个数,第二个ratio<60,1>是时间单位。
所以,
第一个duration<int>,指明片刻个数是整形,默认单位是1秒, twentySeconds(20)创建对象初始化20秒。
第二个duration<double, std::ratio<60>>,片刻个数可以是小数 halfAMinute (0.5)0.5个60秒。
第三个同理。。
1.2 C++标准库定义好的时间段类型
C++ 给我们封装好了不同的时间段类型,
例如:
typedef duration<signed int-type>= 29 bits, ratio<6>> minutes;
我们知道typedef作用,给类起别名。类minutes 就是 duration= 29 bits, ratio<6>>。
所以创建时间段对象,可以直接用 minutes 对象名
std: : chrono: : minutes twentyMinutes(20); //就可以得到一个20分钟的对象。
所以,我们除了可以用std::chrono::duration自己指定一个时间段类型,还可以用标准库中内置的 minutes,seconds时间段类型。
1.3 Duration的算数运算
时间段 可以 进行:
-
加 d1 +d2
-
减 d1-d2
-
乘 d*val
-
除 d/val
-
比较大小 d1<d2
-
等等。。。
这里的关键是 ,两个变量的类型可以不一样。列如
1.4 Duration转换单位(不同的时间片)
可以将duration转化成不同的单位,只有彼此之间存在隐式转换就行。
可以将小时转换 成秒,反向不行。
#include<iostream>
#include<chrono>
using namespace std;
int main()
{
// 创建时间段 对象
std::chrono::seconds twentySeconds(20); //20秒
std::chrono::hours oneDay(24); //一天24小时
std::chrono::milliseconds ms(0);//0毫秒
// 算数操作+隐式转换
ms += oneDay+twentySeconds;// 86 400 000+ 20 000 = 86420 000 milliseconds;
--ms; // 86419999milliseconds;
ms *= 2; // 172839998 milliseconds;
//打印
cout<<ms.count()<<"ms"<<endl;
cout<<std::chrono::nanoseconds(ms).count()<<"ms"<<endl;//ms 转换成纳秒,并显示
system("pause");
return 0;
}
172839998ms
172839998000000ms
Press any key to continue . . .
1.5 duration总结
上面有一些成员属性,以及函数,有C++基础的应该都能看懂。
2.Clock(时钟)和TimePoint(时间点)
前面提到,epoch(起点)和clock相关。
实际上,clock不只影响epoch(起始点),同时不同的clock会有不同的tick周期(时间单位),
例如某个clock,定义起点是1970年一月一日的epoch,周期是 毫秒milliseconds。
2.1 Clock时钟
C++ 标准库提供了三个clock
- 1 system_clock
- 它所表现的timepoint将关联至现行系统的即时时钟(real-time clock)这个clock提供便捷函数to_time_t()和from_time_t().允许我们在timepoint和 “C的系统时间类型” time_t之间转换, 这意味着你可转换至/自日历时间
- 2 steady_clock
- 它保证绝不会被调整。 “因此当实际时间流逝, 其timepoint值绝不会 减少, 而且这些timepoint相对于真实时间都有稳定的前进速率。
- 3 high_resolution_clock
- 它表现的是当前系统中带有最短tick周期的clock.
注意, 标准库井不强制规定上述clock的精准度 epoch “最小和最大timepoint的范围
- 它表现的是当前系统中带有最短tick周期的clock.
2.2 Timepoint
搭配clock,你将可以处理timepoint。
template <class Clock, class Duration = typename Clock::duration>
class time_point
前面提到,
timepoint(时间点) = epoch(起始点) + duration(时间段)
以及表格提到,
timepoint t ;//根据当前的epoch建立一个timepoint
t+= d; //加上一个时间段就可以得到一个新的 timepoint
这里
#include<iostream>
#include<chrono>
using namespace std;
int main()
{
//测试1
// 用system_clock作为时钟,seconds作为单位 创建对象tp 初始化 2 秒
chrono::time_point<std::chrono::system_clock,chrono::seconds> tp(chrono::seconds(2));
// 打印 tp距离起点的 duration (seconds)的个数
cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
//to epoch : 2s
//测试2
// 用system_clock作为时钟,seconds作为单位 创建对象tp 初始化 1分钟
chrono::time_point<std::chrono::system_clock,chrono::seconds> tp1(chrono::minutes(1));
// 打印 tp距离起点的 duration (seconds)的个数
cout << "to epoch : " <<tp1.time_since_epoch().count() << "s" <<endl;
//to epoch : 60s
system("pause");
return 0;
}
to epoch : 2s
to epoch : 60s
3.小结
这里用程序验证的不多,大部分都是一些概念 用来了解chrono库。
后续熟悉的话可能会多验证一下。
参考:C++标准库(第二版)
参考:http://t.csdn.cn/y9wUY