C++11: chrono
2019獨角獸企業重金招聘Python工程師標準>>>
chrono是一個time-library,要使用chrono這個庫需要#include<chrono>.
通常要使用chrono這個庫必定少不了ratio這個庫,需包含#include<ratio>,如果已經#include<chrono>就不需要再#include<ratio>了.
?
我們首先來明確兩個概念:
所謂duration(時間段): 指的是在某時間單位上的一個明確的tick(片刻數).舉個例子,“3分鐘”指的是“3個一分鐘”。
所謂timepoint(時間點):的意思是一個duration和一個epoch(起始點)的組合. 典型的例子是“2000年新年午夜”時間點,它被描述為“自1970年1月1日開始的第1 262 300 400秒”。
ratio:
?template?<intmax_t?Numerator,?intmax_t?Denominator?=?1>?class?ratio;Numerator:? 分子.
Denominator: 分母.
ratio有兩個成員:
ratio::num; //獲得ratio的分子.
ratio::den; //獲得ratio的分母.
#include?<iostream> #include?<ratio> int?main() {std::ratio<1,?4>?oneForth;std::cout<<"Numrator:?"<<oneForth.num<<std::endl;?//輸出:?1.std::cout<<"Denominator:?"<<oneForth.den<<std::endl;?//輸出:?4.return?0; }?
std::chrono::duration
用來表示一段時間.
?template?<class?Rep,?class?Period?=?ratio<1>?> class?duration;Rep: 是一個算術類型(int, double....),或者一類模擬算術類型.
Period: 是一個std::ratio類型.
比如:
?std::chrono::duration<int,?std::ratio<1,1>>?seconds(3);//3秒.由于各種duration的表示是不同的(比如不同的std::duration,用的std::ratio是不同的)因此標準庫還提供了:
template?<class?ToDuration,?class?Rep,?class?Period>constexpr?ToDuration?duration_cast?(const?duration<Rep,Period>&?dtn);ToDuration: 是我們想要轉成duration的類型.
Rep: 是將要被我們轉換的duration類型的算術類型.
Period: 是將要被我轉換的duration類型的std::ratio類型.
duration的成員函數:
?constexpr?rep?count()?const;返回該duration中std::ratio的數量.
?static?constexpr?duration?zero();返回長度為0的duration.
?
?static?constexpr?duration?min();返回此類型之最小的可能.
?
?static?constexpr?duration?zero();返回此類型之最大的可能.
?
#include?<iostream> #include?<ratio> #include?<chrono> int?main() {using?second_type?=?std::chrono::duration<int,?std::ratio<1,?1>>;using?minutes_type?=?std::chrono::duration<int,?std::ratio<60,?1>>;using?hour_type?=?std::chrono::duration<int,?std::ratio<3600,?1>>;?second_type?oneDay1(24*3600);?//一天:24*3600秒.?minutes_type?oneDay2(24*60);?//一天:?24*60分鐘.?hour_type?oneDay3(24);??????//一天:?24小時.?//hour_type?oneDay4(oneDay2);?//error.不能直接轉換.?hour_type?oneDay5(oneDay3);?//?ok.hour_type?oneDay6(std::chrono::duration_cast<hour_type>(oneDay2));?//ok.std::cout<<?oneDay3.count()?<<std::endl;?//輸出:?24.hour_type?threeDay?=?oneDay3?*?3;????????//?3天:?3*24?std::cout<<?threeDay.count()?<<std::endl;//輸出:?3?*?24.?std::chrono::steady_clock::time_point?t1?=?std::chrono::steady_clock::now();?//獲取當前時間.?std::cout<<?"Print?something..."<<std::endl;std::chrono::steady_clock::time_point?t2?=?std::chrono::steady_clock::now();?//獲取當前時間.?std::chrono::steady_clock::duration?d?=?t2?-?t1;?//計算出std::cout<<"Print?something..."<<std::endl;花費的時間.?//注意上面使用的是steady_clock中的duration.?if(d?==?std::chrono::steady_clock::duration::zero()){??//判斷這段時間是不是為0.?std::cout<<"The?interal?clock?did?not?tick\n"<<std::endl;}else{std::cout<<"The?interal?clock?advanced!?"<<?d.count()?<<std::endl;}using?namespace?std::chrono;milliseconds?ms(7255042);hours?hh?=?duration_cast<hours>(ms);minutes?mm?=?duration_cast<minutes>(ms?%?hours(1));?//注意這里ms是個std::chrono::milliseconds類型.?seconds?ss?=?duration_cast<seconds>(ms?%?minutes(1));std::cout<<"hours:?"<<hh.count()<<"?minutes:?"<<mm.count()<<"?seconds:?"<<ss.count()<<std::endl;return?0; }?
Clock:
Clock定義出了一個epoch(起始點)和一個tick(周期,也可以稱作period).例如某個Clock也許定義周期(tick)為毫秒(millionsecond),起始點是UNIX epoch(起始點): 1970年1月1日, 或者定義周期(tick)為納秒(nanosecond),起始點為程序員的開始時間.
Clock還提供了一個類型給“與此Clock關聯”的任何timepoint使用,例如Clock的now()成員函數可以產出一個代表“現在時刻”的timepoint對象.
?
Clock(時鐘)有三種:
std::system_clock;? //它所表現的timepoint(時間點)將關聯到現行系統的即時時鐘.這個clock提供便捷函數to_time_t()和from_time_t(),允許我們在timepoint和C語言的系統時間類型time_t之間轉換。
std::steady_clock;? //它保證絕對不會被調整。因此當實際時間流逝,其timepoint值也絕對不會減少,而且這些timepoint對于真實時間都有穩定的前進速率.
std::high_resolution_clock;? //它表現的是當前系統中帶有最短tick(周期)的clock.(我們常用的時間周期是1秒).也就是說它是更高精度的std::steady_clock
注意,標準庫并不強制規定各種clock的精確度, epoch(起始點), "最大和最小的timepoint的范圍"
?以上3種Clock都具有的成員類型:
Clock::duration? //獲得Clock的duration(時間段)類型.因為一般情況下我們是不知道Clock的計時單位的因此用這個比較保險.
Clock::rep? //獲得上面得到的duration的算術類型比如是:double啊,int啊,等等,等價于:Clock::duration::rep
Clock::period //獲得當前Clock的duration類型的,計時單位,是分? 是秒?其實也就是一個std::ratio類型.
也相當于Clock::duration::period.
Clock::is_steady //如果該Clock是一個steady類型,該值為true.
Clock::now()? //一個static函數,獲得調用該函數時候的當前時刻.
?
?#include?<iostream> #include?<chrono> #include?<type_traits> template<typename?Clock,?typename?=?typename?std::enable_if<?std::is_same<Clock,?std::chrono::steady_clock>::value||?std::is_same<Clock,?std::chrono::system_clock>::value||?std::is_same<Clock,?std::chrono::high_resolution_clock>::value>::type> void?printClockData() {std::cout<<"-?precision:?";using?P?=?typename?Clock::period;?//相當于Clock::duration::period;其實是一個std::ratio類型.if(std::ratio_less_equal<P,?std::milli>::value){using?TT?=?typename?std::ratio_multiply<P,?std::kilo>::type;?//這里的type是std::ratio類型.std::cout<<?std::fixed?<<?double(TT::num)/TT::den?<<?"?milliseconds?"?<<?std::endl;?}else{std::cout<<?std::fixed?<<?double(P::num)/P::den?<<"?seconds"<<std::endl;}?std::cout<<"-?is_steady:?"<<?std::boolalpha?<<?Clock::is_steady?<<?std::endl; } int?main() {std::cout<<?"system_clock:?"?<<std::endl;printClockData<std::chrono::system_clock>();std::chrono::system_clock::time_point?t1?=?std::chrono::system_clock::now();std::cout<<?"system_clock::now()?"<<std::endl;std::chrono::system_clock::duration?sd?=?std::chrono::system_clock::now()?-?t1;std::cout<<?"cost:?"<<?sd.count()?<<std::endl;?//輸出:?0?std::cout<<?"\nhigh_resolution_clock:?"<<std::endl;printClockData<std::chrono::high_resolution_clock>();std::chrono::high_resolution_clock::time_point?t2?=?std::chrono::high_resolution_clock::now();std::cout<<?"high_resolution_clock::now()?"?<<std::endl;std::chrono::high_resolution_clock::duration?hd?=?std::chrono::high_resolution_clock::now()?-?t2;std::cout<<?"cost:?"<<?hd.count()?<<std::endl;?//輸出:?0std::cout<<?"\nsteady_clock:?"<<std::endl;printClockData<std::chrono::steady_clock>();std::chrono::steady_clock::time_point?t3?=?std::chrono::steady_clock::now();std::cout<<?"steady_clock::now()?"<<std::endl;std::chrono::steady_clock::duration?ssd?=?std::chrono::steady_clock::now()?-?t3;std::cout<<"cost:?"<<?ssd.count()?<<std::endl;std::chrono::duration<std::chrono::steady_clock::rep,?std::chrono::steady_clock::period>?du?=?ssd;std::chrono::steady_clock::period?ratioForSteady_clock;std::cout<<?ratioForSteady_clock.num?<<?"?"?<<?ratioForSteady_clock.den?<<std::endl;return?0; }?
Timepoint(時間點):
夾帶(搭配)那些clock,甚至用戶自定義的clock,你將可以處理timepoint。Class time_point提供了相應接口,以一個clock為參數.
template?<class?Clock,?class?Duration?=?typename?Clock::duration>class?time_point;下面4個特定的timepoint扮演了特殊的角色.
1,Epoch, 由任何clock的time_point的default構造函數產出.
2,Current time, 由任何clock的static成員函數now()產出.
3,Minimnum timepoint, 由任何clock的timepoint的static成員函數min()產出.
4,Maximum timepoint, 由任何clocktimepoint的static成員函數max()產出.
#include <iostream> #include <chrono> #include <ctime> #include <string>std::string asString(const std::chrono::system_clock::time_point& tp) {std::time_t t = std::chrono::system_clock::to_time_t(tp);std::string timeString = std::asctime(std::gmtime(&t));//timeString.resize(timeString.size()-1);return timeString; } int main() {std::chrono::system_clock::time_point tp;std::cout<< "epoch: "<< asString(tp) <<std::endl;tp = std::chrono::system_clock::now();std::cout<< "now: "<< asString(tp) <<std::endl;/*tp = std::chrono::system_clock::time_point::min();std::cout<< "min: "<< asString(tp) <<std::endl;*/ //這種情況下是不行的不能得到最小時間點(timepoint).//使用 std::chrono::time_point_cast; using userDefined = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int, std::micro>>;userDefined tp1 = std::chrono::time_point_cast<std::chrono::duration<int, std::micro>>(std::chrono::system_clock::time_point::min());std::cout<< "min: "<< asString(tp1) <<std::endl;//使用 std::chrono::time_point的構造函數. std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int>> t_p;std::chrono::system_clock::time_point tp2(t_p);tp2 = std::chrono::system_clock::time_point::max();std::cout<< "max: "<< asString(tp2)<<std::endl;return 0; }std::chrono::time_point的operator(s):
#include <iostream> #include <ctime> #include <chrono> #include <string>std::string asString(const std::chrono::system_clock::time_point& tp) {std::time_t t = std::chrono::system_clock::to_time_t(tp);std::string timeString(std::ctime(&t));return timeString; }int main() {using Days = std::chrono::duration<int, std::ratio<3600*24>>; using Hours = std::chrono::duration<int, std::ratio<3600>>;using Minutes = std::chrono::duration<int, std::ratio<60>>;using Seconds = std::chrono::duration<int, std::ratio<1,1>>;using Years = std::chrono::duration<unsigned long long, std::ratio<3600*24*365>>;std::chrono::time_point<std::chrono::system_clock> tp1; std::cout<< "Epoch: "<< asString(tp1) <<std::endl; //等同于: asString(std::chrono::system_clock::time_point()); //加1天,23小時,55分鐘.tp1 += Days(1) + Hours(23) + Minutes(55);std::cout<<"Later: " << asString(tp1) << std::endl;std::chrono::duration<std::chrono::system_clock::rep, std::chrono::system_clock::period> dis = tp1 - std::chrono::system_clock::time_point();//注:上面減號后面的 std::chrono::system_clock::time_point();獲得的是Epoch.std::cout<< "Diff: "<< (std::chrono::duration_cast<std::chrono::minutes>(dis)).count()<< " minute(s)." <<std::endl;Days days = std::chrono::duration_cast<Days>(dis);std::cout<< "days: "<< days.count() << " day(s)."<<std::endl;tp1 -= Days(365); //該時間點往前推移一年.std::cout<< "-1 year: " << asString(tp1) <<std::endl; tp1 -= Years(50); //該時間點往前推移五十年.std::cout<< "-50 years: " << asString(tp1) <<std::endl;tp1 -= Years(50); //該時間點往前推移五十年.std::cout<< "again -50 years: " << asString(tp1) <<std::endl;return 0; }16/6/21:
兩種打印時間字符串的方法:
#include <iostream> #include <chrono> #include <ratio>int main() {//case 1: 這種情況下是考慮時區的. std::chrono::time_point<std::chrono::system_clock> tp; //epochstd::time_t t = std::chrono::system_clock::to_time_t(tp);std::string strOne = std::ctime(&t);strOne.resize(strOne.size()-1); //去除尾部的換行符. std::cout<< strOne << std::endl;//case 2: 不考慮時區. std::chrono::time_point<std::chrono::system_clock> tp_one; //epochstd::time_t tTwo = std::chrono::system_clock::to_time_t(tp_one);std::string strTwo = std::asctime(std::gmtime(&tTwo));std::cout<< strTwo <<std::endl;return 0; }?
轉載于:https://my.oschina.net/SHIHUAMarryMe/blog/671830
總結
以上是生活随笔為你收集整理的C++11: chrono的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php strtotime 和 date
- 下一篇: 介绍map.entry接口