前言
接着上一篇文章《C++获取Unix时间戳》继续写。
现在的需求是获取时间间隔。
使用chrono库,这个库实在太强大了,可以通过多种办法实现时间戳的获取,时间单位可以是秒、毫秒、微妙、分钟和小时等。
正文
chrono包含三个部分:时间段类型duration、时间点time_point和时钟clock。
duration
定义为由 Rep 类型的计次数和计次周期Period组成,其中Period是一个编译期有理数常量,表示从一个计次到下一个的秒数。
存储于 duration 的数据仅有 Rep 类型的计次数。若 Rep 是浮点数,则 duration 能表示小数的计次数。 Period 被包含为时长类型的一部分,且只在不同时长间转换时使用。
template <class Rep, class Period = std::ratio<1> >
ratio这个类模版的原型如下,用来表示单位:【用秒表示的时间单位】比如:秒,分,小时等。N代表分子,D代表分母(可省略,默认值是1),所以ratio表示一个分数值。
std::ratio<intmax_t N, intmax_t D = 1>
为了方便,C++标准委员会还预定义了下面这些单位比率,供用户使用
typedef std::ratio<1, 1000000000> nano;
typedef std::ratio<1, 1000000> micro;
typedef std::ratio<1, 1000> milli;
typedef std::ratio<1, 100> centi;
typedef std::ratio<1, 10> deci;
typedef std::ratio< 10, 1> deca;
typedef std::ratio< 100, 1> hecto;
typedef std::ratio< 1000, 1> kilo;
typedef std::ratio< 1000000, 1> mega;
使用方法如下所示。
#include <iostream>
#include <ratio> //表示时间单位的库
#include <chrono>
#include <thread>
int main() {
std::chrono::milliseconds ms(10);//10个tick==10个单位比率
std::chrono::duration<double, ratio<1, 30> > dur(15);
float x = ms.count(); //返回ms这个时间段对象中有多少个单位比率
std::cout << x<< std::endl;
auto y = dur.count();
std::cout << y << std::endl;
auto z = (dur - ms).count();
cout << z << endl;
cout << type_name<decltype(dur - ms)>() << endl;
return 0;
}
运行结果为:(最后的值的单位1/3000s)
ky@skyMac build % /Users/sky/cppProj/cmake_test/build/cmakeTest
10
15
1470
std::__1::chrono::duration<double, std::__1::ratio<1l, 3000l> >
time_point
原型为:
template <class Clock, class Duration = typename Clock::duration>
chrono库中用一个time_point模板类,表示一个时间点,如生日、今天日落时刻等。
通过一个相对epoch的时间间隔duration来实现,epoch就是1970-01-01T00:00:00时刻,对于同一个时钟来说,所有的time_point的epoch都是固定的。这个类可以与标准库ctime结合起来显示时间,ctime内部的time_t类型就是代表这个秒数。
auto tp = std::chrono::system_clock::now();
typedef std::chrono::duration<int, std::ratio<60 * 60 * 24> > days_type; //创建duration时间段--别名
std::chrono::time_point<std::chrono::system_clock, days_type> today ; //创建time_point时间点对象
//std::chrono::system_clock 采用的时钟
//days_type 以这个时间段为单位
today = std::chrono::time_point_cast<days_type>(tp); //单位转换
//把tp转换成以days_type为单位的时间点
int x = today.time_since_epoch().count();
//函数time_from_eproch()用来获得1970年1月1日到time_point时间经过的duration。
//举个例子,如果timepoint以天为单位,函数返回的duration就以天为单位
//返回值的单位跟today一样
std::cout << x << std::endl;
clock
三种时钟类型:system_clock、steady_clock、high_resolution_clock
- system_clock:就类似Windows系统右下角那个时钟,是系统时间。明显这个时钟是可以自己设置的。
system_clock除了now()函数外,还提供了to_time_t()静态成员函数。用于将系统时间转换成熟悉的std::time_t类型,得到了std::time_t类型的值,就可以很方便地打印当前时间了 - steady_clock:是单调的时钟,相当于教练手中的秒表;只会增长,适合用于记录程序耗时,他表示时钟是不能设置的
- high_resolution_clock:是当前系统能够提供的最高精度的时钟;它也是不可以修改的。相当于 steady_clock 的高精度版本。
1. system_clock例子
使用以下代码稳定获取输入前后的时间间隔。
#include <iostream>
#include <ratio> //表示时间单位的库
#include <chrono>
#include<ctime>
int main() {
auto t0 = chrono::system_clock::now();
int a;
cin >> a;
auto tt = chrono::system_clock::now();
auto dt = chrono::duration_cast<chrono::duration<float> >(tt-t0).count();
cout << type_name<decltype(t0)>() << endl;
cout << dt << endl;
}
2. steady_clock
steady_clock的实现是使用monotonic时间,而monotonic时间一般是从boot启动后开始计数的。明显这不能获取日历时间(年月日时分秒)。那么steady_clock有什么用途呢?时间比较!并且是不受用户调整系统时钟影响的时间比较。
3. high_resolution_clock
用法与steady_clock相似,只不过更加精确了。