
前言C11提供了日期时间相关的库chrono通过chrono库可以很方便的处理日期和时间。chrono库主要包含3种类型时间间隔duration、时钟clocks和时间点time_point1、记录时长的durationduration为一个模板类表示时间间隔可以是几秒、几分钟或者几个小时的时间间隔。duration的原型如下123templateclassRep,classPeriod ratio1 classduration;第一模板参数Rep是一个数值类型表示时钟数的类型第二个模板参数是一个默认模板参数std::ratio表示时钟周期它的原型如下123templateintmax_t N,intmax_t D 1classratio;它表示每个时钟周期的秒数其中第一个模板参数N代表分子D代表分母分母默认为1因此ratio代表的是一个分子除以分母的分数值。比如1234567ratio2//代表2秒ratio60//代表1分钟ratio60*60//代表1小时ratio60*60*24//代表1天ratio1, 1000//代表1毫秒ratio1, 1000000//代表1微秒ratio1, 1000000000//代表1纳秒为了方便使用标准库定义了一些常用的时间间隔如时、分、秒、毫秒、微秒和纳秒在chrono命名空间下定义如下(vs2013的源码)123456typedefdurationlonglong, nano nanoseconds;typedefdurationlonglong, micro microseconds;typedefdurationlonglong, milli milliseconds;typedefdurationlonglong seconds;typedefdurationint, ratio60 minutes;typedefdurationint, ratio3600 hours;通过定义这些常用的时间间隔类型我们能方便的使用它们比如线程休眠1234567//休眠100毫秒this_thread::sleep_for(std::chrono::durationint, ratio1, 100(100));this_thread::sleep_for(std::chrono::microseconds(100));//更简单//休眠3秒this_thread::sleep_for(std::chrono::durationint(3));this_thread::sleep_for(std::chrono::seconds(3));//更简单chrono还提供了获取时间间隔的时钟周期数的方法count()它的基本用法如下12345678#includeiostream#includechronointmain(){std::chrono::seconds s(3);//3秒std::chrono::milliseconds ms 2 * s;//6000毫秒std::cout 3 s duration has s.count() ticks\n6000 ms duration has ms.count() ticks\n;}执行结果duration在某些情况下可以进行转换例如当duration的Rep都为整型且源Period要大于目标Period时或者目标duration的Rep为浮点数时可以使用传统类型转化或者隐式调用其单值构造函数不必调用duration_cast123456789101112131415161718192021222324252627intmain(){//目标duration的Rep为doublestd::chrono::milliseconds int_milliseconds(1024);// 1024msstd::chrono::microseconds int_microseconds(1024);// 1024usstd::chrono::durationdouble double_seconds;double_seconds int_microseconds;//1024ms 1.024sdouble_seconds int_milliseconds;//1024us 0.001024s//当duration的Rep都为整型且源Period可被目标Period整除时int_microseconds int_milliseconds;//ms赋值给us可以但是us赋值给ms不可int_milliseconds std::chrono::seconds(1);//s赋值给ms可以但是ms赋值给s不可以//源duration的Rep为double 目标duration的Rep不为double不能转换//std::chrono::milliseconds t1 std::chrono::durationdouble(1024);/** 数据会发生截断时的转化* chrono库提供了duration之间相互转化的函数其定义如下* template class ToDuration, class Rep, class Period* constexpr ToDuration duration_cast(const durationRep,Period d);*/std::chrono::seconds t1 std::chrono::duration_caststd::chrono::seconds(std::chrono::milliseconds(1024));// 1s 1024ms(精度损失)std::chrono::seconds t2 std::chrono::duration_caststd::chrono::seconds(std::chrono::durationdouble(1.024));// 1s 1.024s}时间间隔之间可以做运算计算两端时间间隔的差值的实例如下1234567intmain(){std::chrono::minutes t1(10);std::chrono::seconds t2(50);std::chrono::seconds t3 t1 - t2;cout t3.count() second endl;}执行结果其中t1代表10分钟t2代表50秒t3则是t1减t2也就是600-50550秒。通过调用t3的count()输出差值550个时钟周期因为t3的时钟周期为1秒所以t3表示时间间隔为550秒。值得注意的是duration的加减运算有一定的规则当两个duration时钟周期不相同的时候会先统一成一种时钟然后再作加减运算。统一成一种时钟的规则如下对于ratiox1, y1count1和ratiox2, y2count2。如果x1、x2的最大公约数为xy1、y2的最小公倍数为y那么统一之后的ratio为ratiox, y例如12345678intmain(){std::chrono::durationdouble, std::ratio9, 7 d1(3);std::chrono::durationdouble, std::ratio6, 5 d2(1);auto d3 d1 - d2;cout d3类型 : typeid(d3).name() endl;cout d3.count() endl;}执行结果根据前面介绍的规则对于9/7和6/5分子取最大公约数3分母取最小公倍数35所以统一之后的duration为std::chrono::durationdouble,struct std::ratio3,35。然后再将原来的duration转换为统一的duration最后计算的时钟周期数为((9/7)/(3/35)*3)-((6/5)/(3/35)*1)结果为312、表示时间点的time_pointtime_point表示一个时间点用来获取从它的clock的开始所经过的duration(比如可能是1970.1.1以来的时间间隔)和当前时间可以做一些时间的比较和算术运算可以喝ctime库结合起来显示时间。time_point必须用clock来计时。time_point有一个函数time_from_eproch()用来获得1970年1月1日到time_point时间经过的durationtime_point是一个类模板原型如下1234567templateclassClock,classDuration typenameClock::durationclasstime_point;templateclassClock,classDuration typenameClock::durationclasstime_point;第一个模板参数Clock用来指定所要使用的时钟标准库中有三种时钟system_clocksteady_clock和high_resolution_clock第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration )计算当前时间距离1970年1月1日有多少天12345678910#includeiostream#includechrono#includeratiousingnamespacestd::chrono;intmain(){usingdays_type durationint, std::ratio60 * 60 * 24;time_pointsystem_clock, days_type today time_point_castdays_type(system_clock::now());std::cout today.time_since_epoch().count() days since epoch endl;}执行结果time_point还支持一些算术运算比如两个time_point的差值时钟周期数还可以和duration相加减。要注意不同clock的time_point是不能进行算术运算的。下面例子将展示前一天和后一天的日期12345678910111213#includeiostream#includechrono#includeiomanipusingnamespacestd::chrono;intmain(){system_clock::time_point now system_clock::now();std::time_tprev system_clock::to_time_t(now - hours(24));//返回时间戳std::time_tnext system_clock::to_time_t(now hours(24));//返回时间戳cout One day ago, the time was std::put_time(std::localtime(prev),%Y.%m.%d %H:%M:%S) endl;cout A day later, the time is std::put_time(std::localtime(next),%Y.%m.%d %H:%M:%S) endl;}执行结果3、获取系统时钟的clocksclocks表示当前的系统时钟内部有time_point、duration、Rep、Period等信息主要用来获取当前时间以及实现time_t和time_point的相互转换。clocks包含如下3种时钟-system_clock代表真实时间的挂钟时间具体时间依赖于系统。system_clock保证提供的时间值是一个可读时间-steady_clock不能被“调整” 的时钟并不一定代表真实世界的挂钟时间。保证先后调用now()得到的时间值是不会递减的