C++11 提供一个精度中立的时间程序库称为chrono程序库,定义于<chrono>
此外<chrono>也提供基本的C和POSIX接口用来处理日历时间,也可以使用
于C++11的thread程序库,等待某个线程和程序(主线程)一段时间,个人
认为很不错,对于chrono的代码可以查看标准程序库。
首先chrono有三个个关键概念组成,明白了这三个概念基本可以熟练运用chrono
了:
duration(时间段):指的是某时间单位上的一个明确的tick(片刻数),如:3个1分钟
time_point(时间点):一个duration和一个epoch( 起始点)的组合
clock(时钟):time_point以某个clock为参数,有时钟才有对应的时间点嘛
下面介绍一下具体概念和功能:
定义duration:
duration是一个模版类
duration<type,ratio> D
其中type为tick(片刻数)的类型,可以是int,long int,double等等
当然不同的类型其计算方式和结果不同
ratio 为tick的大小即时间段的单位大小,ratio是一个分数模版类,
在这里其单位为秒详细可以看本博客的有关ratio的文章,标准库有详细介绍,ratio
很强大,其定义形式如下:
ratio<x,y> r;
ratio<x> r;
第一种形式指定分子x分母y大小 得到分数r
第二种形式默认y=1
如定义一个片刻数大小为一秒:ratio<1>或ratio<1,1>
如定义一个片刻数为一天 :ratio<24*60*60>或ratio<24*60*60,1>
下面定义一个tick为1天,tick类型为long int的duration
duration<long int,ratio<24*60*60>> d
chrono预定义有:
纳秒:nanoseconds
微秒:microseconds
毫秒:milliseconds
秒: seconds
分钟:minutes
小时:hours
typedef duration <Rep, ratio<3600,1>> hours;
typedef duration <Rep, ratio<60,1>> minutes;
typedef duration <Rep, ratio<1,1>> seconds;
typedef duration <Rep, ratio<1,1000>> milliseconds;
typedef duration <Rep, ratio<1,1000000>> microseconds;
typedef duration <Rep, ratio<1,1000000000>> nanoseconds;
duration支持不同类型的运算如小时与秒运算
所得结果单位为它们的共公约数,如1min+1s=61s
duratio_cast<type>()支持显式转换
定义time_point
time<time_type,dur=time_type::period>
time_type 为clock类型,dur默认为clock所用的时间间隔
time_point 支持时间点所有的运算
time_point之差为duration类型
time_point可以和duration相互运算
time_point_cast<type>()支持显示转换
注意这里的type并非为time_point类型而是duration类型,
因为只是duration决定了精度,即精度转换
定义clock
chrono中有算个clock
system_clock 系统时钟
steady_clock 稳定时钟,它不随系统调整而改变,这一点在计算程序运行
时间方面特别有用,因为system_clock可因系统调整而导致
前后时间差不追却,而steady_clock之会随时间流失而运行
high_resolution_clock 高精度时钟 ,其实它是system_clock和steady_clock中的一个
下面可以下chrono的功能示例,建议看一下标准库的chrono定义,那里解释
的调理清晰,然后在实现下面的功能这样有利于灵活运用,也有利于记忆
一 用于thread
std::this::sleep_for(chrono::milliseconds(100))
二 输出片刻数
函数 count()
typedef std::chrono::duration<double,std::ratio<24*60*60>> days;
days d(100);
std::cout<<d.count()<<" days"<<std::endl;
三 计算距1970.1.1时间段
函数 time_since_epoch()
静态函数now()
typedf std::chrono::duration<long int,std::ratio<24*60*60>> days;
std::chrono::time_point<system_clock,days> d=std::chrono::system_clock::now();
std::cout<<"since 1910.1.1 "<<d.since_time_epoch().count()<<" days"<<std::endl;
四 C和POSIX系统时间接口
其实就是time_t与time_point之间的转换,只要有了time_t这个数据结构那么C和POSIX
水到渠成了
函数 to_time_t
函数 from_time_t
输出今天的日期
std::chrono::time_point<system_clock> t=std::chrono::system_clock::now();
std::time_t tt=std::chrono::system_clock::to_time_t(t);
std::cout<<std::ctime(&tt)<<std::endl;
五 time_point与duration之间运算
输出昨天的此刻
typedef std::chrono::duration<long int,std::ratio<24*60*60>> days;
std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
now-=days(1);
std::time_t tnow=std::chrono::system_clock::now(now);
std::cout<<"yesterday: "<<std::ctime(&tnow)<<std::endl;
六 duration_cast<type>()显示转换
days t=std::chrono::duration<days>(seconds(10*24*60*60));
七 time_point_cast<type>()显示转换
typedef std::chrono::time_point<std::chrono::system_clock,days> time_point;
time_point t=std::chrono::time_point<time_point>(std::chrono::system_clock::now())
八 制作一个timer
这里我自己封装了一个类模版来实现测试代码执行时间粗略的检测,
我的模版实现了定义各种类型的timer,ns,μs,ms,s,min,...
并且tick类型为double,这避免了由于显示向粗精度转换的精度损失,注意chrono的时间
精度并非按四舍五入的规则而是直接截取,由于默认tick为整型,所以当59s转换为min时
为0min,这正因如此我才换成double
#include<iostream>
#include<chrono>
template<typename T>
class timer
{
public:
typedef std::chrono::duration<double,typename T::period> duration;
typedef std::chrono::time_point<std::chrono::steady_clock,duration> time_point;
timer():base(std::chrono::time_point_cast<duration>(std::chrono::steady_clock::now())){};
const double gettime()const
{
return std::chrono::duration_cast<duration>
(std::chrono::steady_clock::now()-base).count();
}
private:
time_point base;
};
int main()
{
using namespace std::chrono;
timer<microseconds> t;
std::cout<<"hello world!"<<std::endl;
std::cout<<t.gettime()<<" milliseconds"<<std::endl;
}
最后,<<C++标准程序库>>中说明chrono是一个duration/timepoint程序库,不是一个date/time程序库
感觉通过接口连接C和POSIX一切迎刃而解了C++中的std::time_t可以用在任何C和POSIX中time_t的
地方