C++11标准库chrono库使⽤
chrono是C++11新加⼊的⽅便时间⽇期操作的标准库,它既是相应的头⽂件名称,也是std命名空间下的⼀个⼦命名空间,所有时间⽇期相关定义均在std::chrono命名空间下。通过这个新的标准库,可以⾮常⽅便进⾏时间⽇期相关操作。
chrono库主要包含了三种类型:duration, time_point 和 clock。
Duration(时间间隔)
chrono库中⽤⼀个duration模板类,⽤来表⽰⼀段时间间隔,可以表⽰⼏秒钟、⼏分钟或者⼏个⼩时的时间间隔。
原型
template<typename _Rep, typename _Period = ratio<1>>
struct duration
{
typedef _Rep  rep;
...
private:
rep  __r;  //内部维护的计数个数成员
...
};
第⼀个模版参数是数值类型,表⽰时钟个数;第⼆个为std::ratio,⽤来表⽰每个时钟的周期(单位为秒)。
ratio的原型是
template<intmax_t _Num, intmax_t _Den = 1>
struct ratio;
这是⼀个⾮类型模版参数的模版类,intmax_t是定义在cstdint头⽂件中的内置类型。第⼀个参数代表分⼦,第⼆个代表分母,两者表⽰⼀个通⽤的⽐率类型。它们必须在编译期间确定为常量值。分母默认为1,因此ratio<60>代表60,ratio<1, 1000>代表0.001。为了⽅便使⽤,在ratio头⽂件中定义了常⽤⽐率的别名:
typedef ratio<1,1000000000000000000> atto;
typedef ratio<1,1000000000000000> femto;
typedef ratio<1,1000000000000> pico;
typedef ratio<1,1000000000> nano;
typedef ratio<1,1000000> micro;
typedef ratio<1,1000> milli;
typedef ratio<1,100> centi;
typedef ratio<1,10> deci;
typedef ratio<                      10, 1> deca;
typedef ratio<                      100, 1> hecto;
typedef ratio<                    1000, 1> kilo;
typedef ratio<                  1000000, 1> mega;
typedef ratio<              1000000000, 1> giga;
typedef ratio<            1000000000000, 1> tera;
typedef ratio<        1000000000000000, 1> peta;
typedef ratio<      1000000000000000000, 1> exa;
回到duration模板类,默认的⽐率为ratio<1>,也就是⼀个时钟数_Rep代表1秒。为了⽅便使⽤,chrono库定义了如下的常⽤时间单位:
/// nanoseconds
typedef duration<int64_t, nano>    nanoseconds;
/// microseconds
typedef duration<int64_t, micro>    microseconds;
/// milliseconds
typedef duration<int64_t, milli>    milliseconds;
/// seconds
typedef duration<int64_t>      seconds;
/// minutes
typedef duration<int, ratio< 60>>  minutes;
/// hours
typedef duration<int, ratio<3600>>  hours;
通过定义上述常⽤类型,可以⾮常⽅便的使⽤:
/
/线程休眠10秒
std::this_thread::sleep_for(std::chrono::seconds(10));
成员
duration内部维护了周期个数rep和周期period,两者结合⽤来表⽰间隔时间。
count
⽤来获取内部维护的rep类型的周期个数,或称为tick数。即定义变量的实参
chrono::milliseconds ms(10);//10个tick
chrono::duration<double, std::ratio<1, 30>> dur(10.5);//10.5 tick
cout << "ms: " << ms.count() << '\t' << "dur: "<< unt() << endl;
上述代码输出:
ms: 10 dur : 10.5
静态成员函数
duration实例化后,对于给定的rep表⽰周期个数的类型,提供了min、max和zero三个静态成员函数,⽤来获取当前类型能表⽰的最⼩、最⼤周期数和0周期数代表的duration对象。
cout << chrono::seconds::max().count() << endl;
//输出结果为:9223372036854775807
运算操作
duration⽀持基本所有算术运算操作,⽽且不同单位之间的可以⾃动进⾏匹配。这是通过duration_cast模板类实现的。
chrono::minutes t1(5);
chrono::seconds t2(30);
chrono::seconds t3 = t1 - t2;
cout << t3.count() << '\t' << chrono::duration_cast<chrono::minutes>(t3).count() << endl;
//对于类型转换会进⾏舍⼊
//输出结果:270 4
Time point
system的头文件chrono库中⽤⼀个time_point模板类,表⽰⼀个时间点,如⽣⽇、今天⽇落时刻等,通过⼀个相对epoch的时间间隔duration来实
现,epoch就是1970-1-1时刻,对于同⼀个时钟来说,所有的time_point的epoch都是固定的。这个类可以与标准库ctime结合起来显⽰时间,ctime内部的time_t类型就是代表这个秒数。
原型
template<typename _Clock, typename _Dur = typename _Clock::duration>
struct time_point
{
typedef _Clock                      clock;
typedef _Dur                        duration;
typedef typename duration::rep              rep;
typedef typename duration::period          period;
private:
duration __d; //维护的内部duration成员
...
};
第⼀个参数为当前计时使⽤的时钟,可选为“system_colck”、“steady_colck”、“high_resolution_clock”或者是⾃定义的时钟类;
第⼆个参数为时间间隔,默认为使⽤的时钟相同的间隔。
内部维护了⼀个duration私有成员,通过制定的时钟,来确定距离epoch时间点的间隔。
成员
chrono::time_point<system_clock> tp = chrono::system_clock::now();
cout << tp.time_since_epoch().count() << endl;
//输出为:1452672734311762303
//system_clock的ratio为nano
运算
与duration类似,time_point也提供了静态成员min和max,以及算术运算操作,这些都是通过内部维护的duration成员进⾏
的,duration成员的各种操作由前⾯所述的提供保障,time_point就只需要通过time_since_epoch获取私有duration成员进⾏调⽤即可。还提供了与duration直接进⾏”+=”和“-=”的运算操作,对于普通的算术运算,如果有⼀个操作数类型为duration,则是在time_point 类型操作数内部维护的duration成员上进⾏操作,则返回类型为time_point;当两者均为time_point类型时,返回类型为⼆者维护的duration成员之差,从⽽返回类型也为duration。
表⽰当前系统时钟,共有三种:
system_clock:从系统获取时钟
steady_clock:不能被修改的时钟
high_resolution_clock:⾼精度时钟,实际上是system_clock或者steady_clock的别名,最⼩精度是纳秒
system_clock
system_clock 提供三个静态的函数,可以⽤于time_point提供了与C API的时间交互的良好定义。因此,可以很容易与time_t类型打交道。接⼝函数如下:
//get current time
static time_point now() noexcept;
//time_point conver to time_t
static time_t to_time_t (const time_point& tp) noexcept;
//convert time_t to time_oint
std::chrono::system_clock::from_time_t
static time_point from_time_t (time_t t) noexcept;
system_clock 和ctime函数使⽤demo:
#include <iostream>
#include <ctime>
#include <chrono>
int main ()
{
using std::chrono::system_clock;
std::chrono::duration<int,std::ratio<60*60*24> > one_day (1);
//current time
system_clock::time_point today = system_clock::now();
/
/tomorrow time
system_clock::time_point tomorrow = today + one_day;
//convert time type
time_t tmTomorrow = system_clock::to_time_t ( tomorrow );
//time string
std::cout << "tomorrow will be: " << ctime(&tmTomorrow);
struct tm *p;
p = localtime(&tmTomorrow); /*转换为struct tm结构的当地时间*/
printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday);
return0;
}
运⾏结果:
tomorrow will be: Sun Feb 11 09:13:07 2018
2018/2/11
steady_clock
steady_clock 专门⽤于计算时间差的⼯具,steady_clock 类只有⼀个静态函数now(),⽤于获取当前的时间,计算时间差的⽅式如下:
#include <iostream>
#include <chrono>
int main()
{
typedef std::chrono::steady_clock  STEADY_CLOCK;
STEADY_CLOCK::time_point t1 = STEADY_CLOCK::now();
std::cout << "print 1000 stars" << std::endl;
for (int i=1; i<=1000; ++i)
{
std::cout << "*";
if (0 == i % 50)
{
std::cout << "\n";
}
}
std::cout << std::endl;
STEADY_CLOCK::time_point t2 = STEADY_CLOCK::now();
/
/毫秒
std::chrono::duration<double, std::milli> dTimeSpan = std::chrono::duration<double,std::milli>(t2-t1);
std::cout << "print start time span : " << unt() << "ms\n";
}
运⾏结果:
print 1000 stars
****************************....
print start time span : 0.091333ms

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。