chrono是C++11新加入的方便時間日期操做的標準庫,它既是相應的頭文件名稱,也是std命名空間下的一個子命名空間,全部時間日期相關定義均在std::chrono命名空間下。經過這個新的標準庫,能夠很是方便進行時間日期相關操做。
chrono庫主要包含了三種類型:duration, time_point 和 clock。css
chrono庫中用一個duration模板類,用來表示一段時間間隔,能夠表示幾秒鐘、幾分鐘或者幾個小時的時間間隔。ios
原型ruby
template<typename _Rep, typename _Period = ratio<1>>
struct duration
{
typedef _Rep rep;
...
private:
rep __r; //內部維護的計數個數成員
...
};
第一個模版參數是數值類型,表示時鐘個數;第二個爲std::ratio,用來表示每一個時鐘的週期(單位爲秒)。
ratio的原型是markdown
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;
經過定義上述經常使用類型,能夠很是方便的使用:ui
//線程休眠10秒
std::this_thread::sleep_for(std::chrono::seconds(10));
成員this
duration內部維護了週期個數rep和週期period,二者結合用來表示間隔時間。spa
count.net
用來獲取內部維護的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: "<< dur.count() << 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
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
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);
return 0;
}
運行結果:
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 : " << dTimeSpan.count() << "ms\n";
}
運行結果:
print 1000 stars
****************************....
print start time span : 0.091333ms
參考資料:
http://www.cplusplus.com/reference/chrono/
http://blog.csdn.net/u010487568/article/details/50512770