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;
    
}

 

 

 

 

posted @ 2020-08-20 03:18  天子骄龙  阅读(2723)  评论(0编辑  收藏  举报