C++11标准库chrono库--时间日期库
chrono是C++11新加入的方便时间日期操作的标准库,它既是相应的头文件名称,也是std命名空间下的一个子命名空间,所有时间日期相关定义均在std::chrono命名空间下。通过这个新的标准库,可以非常方便进行时间日期相关操作。
chrono库主要包含了三种类型:duration, time_point 和 clock
需要:
#include <ratio> //表示时间单位的库
#include <chrono>
duration 时间段类型
/* ratio这个类模版的原型:格式:std::ratio<intmax_t N, intmax_t D = 1> 用来表示单位:【用秒表示的时间单位】比如:秒,分,小时等 N代表分子,D代表分母(可省略,默认值是1),所以ratio表示一个分数值
为了方便,C++标准委员会还预定义了下面这些单位比率,供用户使用
typedef std::ratio<1, 1000000000000000000> atto;
typedef std::ratio<1, 1000000000000000> femto;
typedef std::ratio<1, 1000000000000> pico;
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;
typedef std::ratio< 1000000000, 1> giga;
typedef std::ratio< 1000000000000, 1> tera;
typedef std::ratio< 1000000000000000, 1> peta;
typedef std::ratio< 1000000000000000000, 1> exa;
ratio<3600, 1> 小时 ratio<60, 1> 分 ratio<1, 1> 秒 ratio<1, 1000> 毫秒 milli ratio<1, 1000000> 微妙 micro ratio<1, 1000000000> 纳秒 nano 注意,我们自己可以定义:比如ratio<1, 2>表示单位时间是0.5秒 */
#include <iostream> #include <ratio> //表示时间单位的库 #include <chrono> #include <thread> int main() { std::chrono::duration<int, std::ratio<60 * 60>> h_oneday(24); // 创建一段时间对象 24h /* std::chrono::duration 表示一段时间 int是数据类型,可以是float double等 std::ratio<60 * 60> 是单位比率,默认为std::ratio<1> h_oneday(24) 表示时间是:24*单位比率=24h
24(rep)理解成周期数 单位比率理解成一个周期 */ std::chrono::duration<int> s_oneday(60 * 60 * 24); // 86400s //使用默认单位比率std::ratio<1> /* 为了方便使用,chrono库定义了如下的常用时间单位: typedef duration<int64_t, nano> nanoseconds; //纳秒 typedef duration<int64_t, micro> microseconds; //微妙 typedef duration<int64_t, milli> milliseconds; //毫秒 typedef duration<int64_t> seconds; //秒 typedef duration<int, ratio< 60>> minutes; //分 typedef duration<int, ratio<3600>> hours; //时 */ //通过定义上述常用类型,可以非常方便的使用: for (int i = 0; i < 100; i++) { std::cout << "i=" << i << std::endl; std::this_thread::sleep_for(std::chrono::seconds(3)); //本线程休眠3秒 } return 0; }
#include <iostream> #include <ratio> //表示时间单位的库 #include <chrono> #include <thread> int main() { std::chrono::milliseconds ms(10);//10个tick==10个单位比率 std::chrono::duration<double, std::ratio<1, 30>> dur(10.5);//10.5 tick==10.5个单位比率 float x = ms.count(); //返回ms这个时间段对象中有多少个单位比率 std::cout << x<< std::endl; x = dur.count(); std::cout << x << std::endl; //duration实例化后,对于给定的rep表示周期个数的类型,提供了min、max和zero三个静态成员函数,用来获取当前类型能表示的最小、最大周期数和0周期数 double y = std::chrono::seconds::max().count(); //返回seconds的最大周期数 std::cout << y << std::endl; y = std::chrono::seconds::min().count();//返回seconds的最小周期数 std::cout << y << std::endl; y = std::chrono::seconds::zero().count();//返回seconds的0周期数 std::cout << y << std::endl; return 0; }
//duration支持基本所有算术运算操作,而且不同单位之间的可以自动进行匹配。这是通过duration_cast模板类实现的 std::chrono::minutes t1(5); //创建以分为单位的时间段 std::chrono::seconds t2(30); std::chrono::seconds t3 = t1 - t2; std::cout << t3.count() << std::endl; float x = std::chrono::duration_cast<std::chrono::minutes>(t3).count(); //单位转换 //把t3的单位转换为分并返回 //注意:对于类型转换返回值只取指定单位的整数,零头舍去 std::cout << x << std::endl;
时钟clock
C++11为我们提供了三种时钟类型:system_clock、steady_clock、high_resolution_clock
这三个时间类都提供了rep【周期】、period【单位比率】、duration成员类型
这三个时钟类都提供了一个静态成员函数now()用于获取当前时间,该函数的返回值是一个time_point类型
注意:虽然这三个时钟都很多相同的成员类型和成员函数,但它们是没有亲缘关系的。这三个时钟类型都是类,并非模板类
这三个时钟有什么区别呢?
system_clock:就类似Windows系统右下角那个时钟,是系统时间。明显这个时钟是可以自己设置的。
system_clock除了now()函数外,还提供了to_time_t()静态成员函数。用于将系统时间转换成熟悉的std::time_t类型,得到了std::time_t类型的值,就可以很方便地打印当前时间了
steady_clock:是单调的时钟,相当于教练手中的秒表;只会增长,适合用于记录程序耗时,他表示时钟是不能设置的
high_resolution_clock:是当前系统能够提供的最高精度的时钟;它也是不可以修改的。相当于 steady_clock 的高精度版本
system_clock例子
#include <iostream> #include <ratio> //表示时间单位的库 #include <chrono> #include<ctime> int main() { auto tp = std::chrono::system_clock::now(); //获取系统当前时间点 std::time_t cur_time = std::chrono::system_clock::to_time_t(tp); //将时间转换为ctime的time_t格式 char stime[30]; errno_t err=ctime_s(stime, sizeof(stime), &cur_time); //转换为字符串 std::cout << stime << std::endl; return 0; }
注意:不要将steady_clock、high_resolution_clock时钟的now()返回值作为to_time_t的参数,这会导致编译通不过。因为类型不匹配
auto自动为此变量选择匹配的类型
steady_clock例子
steady_clock的实现是使用monotonic时间,而monotonic时间一般是从boot启动后开始计数的。明显这不能获取日历时间(年月日时分秒)。那么steady_clock有什么用途呢?时间比较!并且是不受用户调整系统时钟影响的时间比较
#include <iostream> #include <ratio> //表示时间单位的库 #include <chrono> #include<ctime> #include <thread> int main() { auto begin = std::chrono::steady_clock::now(); //获取系统启动后到现在的时间点 for (int i = 0; i < 10; ++i) { std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << i << std::endl; } auto end = std::chrono::steady_clock::now(); auto diff = (end - begin).count(); //返回时间差--【单位:纳秒】 std::cout << "diff="<<diff << std::endl; return 0; }
time_point 时间点类型
chrono库中用一个time_point模板类,表示一个时间点,如生日、今天日落时刻等
通过一个相对epoch的时间间隔duration来实现,epoch就是1970-01-01T00:00:00时刻,对于同一个时钟来说,所有的time_point的epoch都是固定的。这个类可以与标准库ctime结合起来显示时间,ctime内部的time_t类型就是代表这个秒数。
#include <iostream> #include <chrono> #include<ctime> int main() { //std::chrono::system_clock::time_point tp; //创建一个time_point类的时间点对象--格式一 std::chrono::time_point<std::chrono::system_clock> tp; //创建一个time_point类的时间点对象--格式二 //system_clock 采用的时钟 tp= std::chrono::system_clock::now();//获取系统现在的时间点--time_point时间点 std::time_t cur_time = std::chrono::system_clock::to_time_t(tp); char stime[30]; errno_t err = ctime_s(stime, sizeof(stime), &cur_time); std::cout << stime << std::endl; return 0; }
#include <iostream> #include <chrono> #include<ctime> int main() { std::chrono::time_point<std::chrono::system_clock> tp; 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; return 0; }
#include <iostream> #include <chrono> #include<ctime> #include <ctime> int main() { std::chrono::time_point<std::chrono::system_clock> tp; tp= std::chrono::system_clock::now(); std::chrono::duration<int, std::ratio<60 * 60 * 24>> one_day(1); //创建duration时间段对象 std::chrono::system_clock::time_point today = std::chrono::system_clock::now(); std::chrono::system_clock::time_point tomorrow = today + one_day; //两个时间点相加 std::time_t tt; char stime[30]; tt = std::chrono::system_clock::to_time_t(today); //把time_point转换成time_t errno_t err = ctime_s(stime, sizeof(stime), &tt); std::cout << "today is: " << stime << std::endl; tt = std::chrono::system_clock::to_time_t(tomorrow); err = ctime_s(stime, sizeof(stime), &tt); std::cout << "tomorrow will be: " << stime << std::endl; tomorrow = std::chrono::system_clock::from_time_t(tt); //从time_t转换成time_point return 0; }