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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM