C++11: chrono
2016-05-08 00:00
561 查看
chrono是一个time-library,要使用chrono这个库需要#include<chrono>.
通常要使用chrono这个库必定少不了ratio这个库,需包含#include<ratio>,如果已经#include<chrono>就不需要再#include<ratio>了.
我们首先来明确两个概念:
所谓duration(时间段): 指的是在某时间单位上的一个明确的tick(片刻数).举个例子,“3分钟”指的是“3个一分钟”。
所谓timepoint(时间点):的意思是一个duration和一个epoch(起始点)的组合. 典型的例子是“2000年新年午夜”时间点,它被描述为“自1970年1月1日开始的第1 262 300 400秒”。
ratio:
Numerator: 分子.
Denominator: 分母.
ratio有两个成员:
ratio::num; //获得ratio的分子.
ratio::den; //获得ratio的分母.
std::chrono::duration
用来表示一段时间.
Rep: 是一个算术类型(int, double....),或者一类模拟算术类型.
Period: 是一个std::ratio类型.
比如:
由于各种duration的表示是不同的(比如不同的std::duration,用的std::ratio是不同的)因此标准库还提供了:
ToDuration: 是我们想要转成duration的类型.
Rep: 是将要被我们转换的duration类型的算术类型.
Period: 是将要被我转换的duration类型的std::ratio类型.
duration的成员函数:
返回该duration中std::ratio的数量.
返回长度为0的duration.
返回此类型之最小的可能.
返回此类型之最大的可能.
Clock:
Clock定义出了一个epoch(起始点)和一个tick(周期,也可以称作period).例如某个Clock也许定义周期(tick)为毫秒(millionsecond),起始点是UNIX epoch(起始点): 1970年1月1日, 或者定义周期(tick)为纳秒(nanosecond),起始点为程序员的开始时间.
Clock还提供了一个类型给“与此Clock关联”的任何timepoint使用,例如Clock的now()成员函数可以产出一个代表“现在时刻”的timepoint对象.
Clock(时钟)有三种:
std::system_clock; //它所表现的timepoint(时间点)将关联到现行系统的即时时钟.这个clock提供便捷函数to_time_t()和from_time_t(),允许我们在timepoint和C语言的系统时间类型time_t之间转换。
std::steady_clock; //它保证绝对不会被调整。因此当实际时间流逝,其timepoint值也绝对不会减少,而且这些timepoint对于真实时间都有稳定的前进速率.
std::high_resolution_clock; //它表现的是当前系统中带有最短tick(周期)的clock.(我们常用的时间周期是1秒).也就是说它是更高精度的std::steady_clock
注意,标准库并不强制规定各种clock的精确度, epoch(起始点), "最大和最小的timepoint的范围"
以上3种Clock都具有的成员类型:
Clock::duration //获得Clock的duration(时间段)类型.因为一般情况下我们是不知道Clock的计时单位的因此用这个比较保险.
Clock::rep //获得上面得到的duration的算术类型比如是:double啊,int啊,等等,等价于:Clock::duration::rep
Clock::period //获得当前Clock的duration类型的,计时单位,是分? 是秒?其实也就是一个std::ratio类型.
也相当于Clock::duration::period.
Clock::is_steady //如果该Clock是一个steady类型,该值为true.
Clock::now() //一个static函数,获得调用该函数时候的当前时刻.
Timepoint(时间点):
夹带(搭配)那些clock,甚至用户自定义的clock,你将可以处理timepoint。Class time_point提供了相应接口,以一个clock为参数.
下面4个特定的timepoint扮演了特殊的角色.
1,Epoch, 由任何clock的time_point的default构造函数产出.
2,Current time, 由任何clock的static成员函数now()产出.
3,Minimnum timepoint, 由任何clock的timepoint的static成员函数min()产出.
4,Maximum timepoint, 由任何clocktimepoint的static成员函数max()产出.
std::chrono::time_point的operator(s):
16/6/21:
两种打印时间字符串的方法:
通常要使用chrono这个库必定少不了ratio这个库,需包含#include<ratio>,如果已经#include<chrono>就不需要再#include<ratio>了.
我们首先来明确两个概念:
所谓duration(时间段): 指的是在某时间单位上的一个明确的tick(片刻数).举个例子,“3分钟”指的是“3个一分钟”。
所谓timepoint(时间点):的意思是一个duration和一个epoch(起始点)的组合. 典型的例子是“2000年新年午夜”时间点,它被描述为“自1970年1月1日开始的第1 262 300 400秒”。
ratio:
template <intmax_t Numerator, intmax_t Denominator = 1> class ratio;
Numerator: 分子.
Denominator: 分母.
ratio有两个成员:
ratio::num; //获得ratio的分子.
ratio::den; //获得ratio的分母.
#include <iostream> #include <ratio>
int main() { std::ratio<1, 4> oneForth; std::cout<<"Numrator: "<<oneForth.num<<std::endl; //输出: 1. std::cout<<"Denominator: "<<oneForth.den<<std::endl; //输出: 4. return 0; }
std::chrono::duration
用来表示一段时间.
template <class Rep, class Period = ratio<1> > class duration;
Rep: 是一个算术类型(int, double....),或者一类模拟算术类型.
Period: 是一个std::ratio类型.
比如:
std::chrono::duration<int, std::ratio<1,1>> seconds(3);//3秒.
由于各种duration的表示是不同的(比如不同的std::duration,用的std::ratio是不同的)因此标准库还提供了:
template <class ToDuration, class Rep, class Period> constexpr ToDuration duration_cast (const duration<Rep,Period>& dtn);
ToDuration: 是我们想要转成duration的类型.
Rep: 是将要被我们转换的duration类型的算术类型.
Period: 是将要被我转换的duration类型的std::ratio类型.
duration的成员函数:
constexpr rep count() const;
返回该duration中std::ratio的数量.
static constexpr duration zero();
返回长度为0的duration.
static constexpr duration min();
返回此类型之最小的可能.
static constexpr duration zero();
返回此类型之最大的可能.
#include <iostream> #include <ratio>
#include <chrono>
int main() { using second_type = std::chrono::duration<int, std::ratio<1, 1>>; using minutes_type = std::chrono::duration<int, std::ratio<60, 1>>; using hour_type = std::chrono::duration<int, std::ratio<3600, 1>>; second_type oneDay1(24*3600); //一天:24*3600秒. minutes_type oneDay2(24*60); //一天: 24*60分钟. hour_type oneDay3(24); //一天: 24小时. //hour_type oneDay4(oneDay2); //error.不能直接转换. hour_type oneDay5(oneDay3); // ok. hour_type oneDay6(std::chrono::duration_cast<hour_type>(oneDay2)); //ok. std::cout<< oneDay3.count() <<std::endl; //输出: 24. hour_type threeDay = oneDay3 * 3; // 3天: 3*24 std::cout<< threeDay.count() <<std::endl;//输出: 3 * 24. std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); //获取当前时间. std::cout<< "Print something..."<<std::endl; std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); //获取当前时间. std::chrono::steady_clock::duration d = t2 - t1; //计算出std::cout<<"Print something..."<<std::endl;花费的时间. //注意上面使用的是steady_clock中的duration. if(d == std::chrono::steady_clock::duration::zero()){ //判断这段时间是不是为0. std::cout<<"The interal clock did not tick\n"<<std::endl; }else{ std::cout<<"The interal clock advanced! "<< d.count() <<std::endl; } using namespace std::chrono; milliseconds ms(7255042); hours hh = duration_cast<hours>(ms); minutes mm = duration_cast<minutes>(ms % hours(1)); //注意这里ms是个std::chrono::milliseconds类型. seconds ss = duration_cast<seconds>(ms % minutes(1)); std::cout<<"hours: "<<hh.count()<<" minutes: "<<mm.count()<<" seconds: "<<ss.count()<<std::endl; return 0; }
Clock:
Clock定义出了一个epoch(起始点)和一个tick(周期,也可以称作period).例如某个Clock也许定义周期(tick)为毫秒(millionsecond),起始点是UNIX epoch(起始点): 1970年1月1日, 或者定义周期(tick)为纳秒(nanosecond),起始点为程序员的开始时间.
Clock还提供了一个类型给“与此Clock关联”的任何timepoint使用,例如Clock的now()成员函数可以产出一个代表“现在时刻”的timepoint对象.
Clock(时钟)有三种:
std::system_clock; //它所表现的timepoint(时间点)将关联到现行系统的即时时钟.这个clock提供便捷函数to_time_t()和from_time_t(),允许我们在timepoint和C语言的系统时间类型time_t之间转换。
std::steady_clock; //它保证绝对不会被调整。因此当实际时间流逝,其timepoint值也绝对不会减少,而且这些timepoint对于真实时间都有稳定的前进速率.
std::high_resolution_clock; //它表现的是当前系统中带有最短tick(周期)的clock.(我们常用的时间周期是1秒).也就是说它是更高精度的std::steady_clock
注意,标准库并不强制规定各种clock的精确度, epoch(起始点), "最大和最小的timepoint的范围"
以上3种Clock都具有的成员类型:
Clock::duration //获得Clock的duration(时间段)类型.因为一般情况下我们是不知道Clock的计时单位的因此用这个比较保险.
Clock::rep //获得上面得到的duration的算术类型比如是:double啊,int啊,等等,等价于:Clock::duration::rep
Clock::period //获得当前Clock的duration类型的,计时单位,是分? 是秒?其实也就是一个std::ratio类型.
也相当于Clock::duration::period.
Clock::is_steady //如果该Clock是一个steady类型,该值为true.
Clock::now() //一个static函数,获得调用该函数时候的当前时刻.
#include <iostream> #include <chrono> #include <type_traits>
template<typename Clock, typename = typename std::enable_if< std::is_same<Clock, std::chrono::steady_clock>::value || std::is_same<Clock, std::chrono::system_clock>::value || std::is_same<Clock, std::chrono::high_resolution_clock>::value >::type> void printClockData() { std::cout<<"- precision: "; using P = typename Clock::period; //相当于Clock::duration::period;其实是一个std::ratio类型. if(std::ratio_less_equal<P, std::milli>::value){ using TT = typename std::ratio_multiply<P, std::kilo>::type; //这里的type是std::ratio类型. std::cout<< std::fixed << double(TT::num)/TT::den << " milliseconds " << std::endl; }else{ std::cout<< std::fixed << double(P::num)/P::den <<" seconds"<<std::endl; } std::cout<<"- is_steady: "<< std::boolalpha << Clock::is_steady << std::endl; }
int main() { std::cout<< "system_clock: " <<std::endl; printClockData<std::chrono::system_clock>(); std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now(); std::cout<< "system_clock::now() "<<std::endl; std::chrono::system_clock::duration sd = std::chrono::system_clock::now() - t1; std::cout<< "cost: "<< sd.count() <<std::endl; //输出: 0 std::cout<< "\nhigh_resolution_clock: "<<std::endl; printClockData<std::chrono::high_resolution_clock>(); std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); std::cout<< "high_resolution_clock::now() " <<std::endl; std::chrono::high_resolution_clock::duration hd = std::chrono::high_resolution_clock::now() - t2; std::cout<< "cost: "<< hd.count() <<std::endl; //输出: 0 std::cout<< "\nsteady_clock: "<<std::endl; printClockData<std::chrono::steady_clock>(); std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now(); std::cout<< "steady_clock::now() "<<std::endl; std::chrono::steady_clock::duration ssd = std::chrono::steady_clock::now() - t3; std::cout<<"cost: "<< ssd.count() <<std::endl; std::chrono::duration<std::chrono::steady_clock::rep, std::chrono::steady_clock::period> du = ssd; std::chrono::steady_clock::period ratioForSteady_clock; std::cout<< ratioForSteady_clock.num << " " << ratioForSteady_clock.den <<std::endl; return 0; }
Timepoint(时间点):
夹带(搭配)那些clock,甚至用户自定义的clock,你将可以处理timepoint。Class time_point提供了相应接口,以一个clock为参数.
template <class Clock, class Duration = typename Clock::duration> class time_point;
下面4个特定的timepoint扮演了特殊的角色.
1,Epoch, 由任何clock的time_point的default构造函数产出.
2,Current time, 由任何clock的static成员函数now()产出.
3,Minimnum timepoint, 由任何clock的timepoint的static成员函数min()产出.
4,Maximum timepoint, 由任何clocktimepoint的static成员函数max()产出.
#include <iostream> #include <chrono> #include <ctime> #include <string> std::string asString(const std::chrono::system_clock::time_point& tp) { std::time_t t = std::chrono::system_clock::to_time_t(tp); std::string timeString = std::asctime(std::gmtime(&t)); //timeString.resize(timeString.size()-1); return timeString; } int main() { std::chrono::system_clock::time_point tp; std::cout<< "epoch: "<< asString(tp) <<std::endl; tp = std::chrono::system_clock::now(); std::cout<< "now: "<< asString(tp) <<std::endl; /*tp = std::chrono::system_clock::time_point::min(); std::cout<< "min: "<< asString(tp) <<std::endl;*/ //这种情况下是不行的不能得到最小时间点(timepoint). //使用 std::chrono::time_point_cast; using userDefined = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int, std::micro>>; userDefined tp1 = std::chrono::time_point_cast<std::chrono::duration<int, std::micro>>(std::chrono::system_clock::time_point::min()); std::cout<< "min: "<< asString(tp1) <<std::endl; //使用 std::chrono::time_point的构造函数. std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int>> t_p; std::chrono::system_clock::time_point tp2(t_p); tp2 = std::chrono::system_clock::time_point::max(); std::cout<< "max: "<< asString(tp2)<<std::endl; return 0; }
std::chrono::time_point的operator(s):
#include <iostream> #include <ctime> #include <chrono> #include <string> std::string asString(const std::chrono::system_clock::time_point& tp) { std::time_t t = std::chrono::system_clock::to_time_t(tp); std::string timeString(std::ctime(&t)); return timeString; } int main() { using Days = std::chrono::duration<int, std::ratio<3600*24>>; using Hours = std::chrono::duration<int, std::ratio<3600>>; using Minutes = std::chrono::duration<int, std::ratio<60>>; using Seconds = std::chrono::duration<int, std::ratio<1,1>>; using Years = std::chrono::duration<unsigned long long, std::ratio<3600*24*365>>; std::chrono::time_point<std::chrono::system_clock> tp1; std::cout<< "Epoch: "<< asString(tp1) <<std::endl; //等同于: asString(std::chrono::system_clock::time_point()); //加1天,23小时,55分钟. tp1 += Days(1) + Hours(23) + Minutes(55); std::cout<<"Later: " << asString(tp1) << std::endl; std::chrono::duration<std::chrono::system_clock::rep, std::chrono::system_clock::period> dis = tp1 - std::chrono::system_clock::time_point(); //注:上面减号后面的 std::chrono::system_clock::time_point();获得的是Epoch. std::cout<< "Diff: " << (std::chrono::duration_cast<std::chrono::minutes>(dis)).count() << " minute(s)." <<std::endl; Days days = std::chrono::duration_cast<Days>(dis); std::cout<< "days: " << days.count() << " day(s)."<<std::endl; tp1 -= Days(365); //该时间点往前推移一年. std::cout<< "-1 year: " << asString(tp1) <<std::endl; tp1 -= Years(50); //该时间点往前推移五十年. std::cout<< "-50 years: " << asString(tp1) <<std::endl; tp1 -= Years(50); //该时间点往前推移五十年. std::cout<< "again -50 years: " << asString(tp1) <<std::endl; return 0; }
16/6/21:
两种打印时间字符串的方法:
#include <iostream> #include <chrono> #include <ratio> int main() { //case 1: 这种情况下是考虑时区的. std::chrono::time_point<std::chrono::system_clock> tp; //epoch std::time_t t = std::chrono::system_clock::to_time_t(tp); std::string strOne = std::ctime(&t); strOne.resize(strOne.size()-1); //去除尾部的换行符. std::cout<< strOne << std::endl; //case 2: 不考虑时区. std::chrono::time_point<std::chrono::system_clock> tp_one; //epoch std::time_t tTwo = std::chrono::system_clock::to_time_t(tp_one); std::string strTwo = std::asctime(std::gmtime(&tTwo)); std::cout<< strTwo <<std::endl; return 0; }
相关文章推荐
- C++学习零碎知识
- 弄清楚C语言中的取反和反码
- 循环队列(C语言实现)
- C语言中,结构体成员变量的点和箭头
- 算法导论——红黑树插入算法C++实现
- C++ 从数据库读取数据,将数据显示在界面上的TreeCtrl上
- c++作业5,数组分离,成绩,数组选择
- c++第五次作业
- 链表1
- 值得推荐的C/C++框架和库
- C++实验5--数组分离
- 如何用c语言调用c++做成的动态链接库
- c++实验5-求和
- 小白说编译原理-9-最简单minus-c语言编译器
- c++ 中 pair 的 使用方法
- C++ Note
- c++实验5-数组选择
- 小白说编译原理-8-简单minus-c语言编译树(支撑类)
- 在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?----转
- 《深度探索C++对象模型》学习笔记之Data语意学