Boost庫 對時間和日期的處理 date_timer庫
/Boost 對時間和日期的處理 提供了timer和data_time 庫/ //有關timer庫提供了簡易的度量時間和進度顯示的功能可以用于性能測試等需要計時的任務 /* timer 的三個組件 計時器類timer progress_timer和進度指示類progress_display timer 可測量時間的流逝,提供毫秒級的計時精確度include<boost\timer.hpp>
include<iostream>
using namespace boost; using namespace std; int main() { timer t;//開始計時 cout << "max timespan:" << t.elapsed_max()/3600 << "h" << endl;//測量時間的最大時間范圍 cout << "min timespan" << t.elapsed_min()<< "s" << endl;//最小精確度 cout << "now time elapsed" << t.elapsed() << "s" << endl;//已經流逝的時間 }*/
/ 使用建議:不適合高精度高的計時,window下精度1/1000,linux 下為1/1000000 難以做到跨平臺/ /*--------------------progress_timer------------------- 繼承自timer 會在析構時自動輸出時間 需包含頭文件<> 可以在構造函數指定I/O流那么在析構時會寫到指定到I/O流 擴展計時精度: 使用模板技術仿造progress_timer 編寫新類 new_progress_timer 實現任意精度的輸出 同樣繼承自timer類 只是變成了模板類N指定精確度默認為2
include<boost\progress.hpp>
include<boost\static_assert.hpp>
template<int N=2> class new_progress_timer :public boost::timer { public: //構造函數初始化輸出流m_os 在window平臺下n>3無意義/ new_progress_timer(std::ostream& os = std::cout) :m_os(os) { BOOST_STATIC_ASSERT(N >= 0 && N <= 10); } ~new_progress_timer() { try{ //保存流的狀態 std::istream::fmtflags old_flags = m_os.setf(std::istream::fixed, std::istream::floatfield); std::streamsize old_prec = m_os.precision(N); m_os << elapsed() << "s\n"<< std::endl; //恢復流的狀態 m_os.flags(old_flags); m_os.precision(old_prec);
} catch (...){}//析構函數絕對不能拋出異常 } private: std::ostream& m_os; }; template<> class new_progress_timer<2>:public boost::progress_timer//對n=2的模板的化 {
}; int main() { //{ //boost::progress_timer t; //std::cout << t.elapsed() << std::endl; //do something; //} //模板的使用 new_progress_timer<10> t; //do someting; } / //----------------------progress_display / 可以在控制臺上顯示程序的執行很耗時那么她能夠提供一個友好的用戶界面 是一個獨立類和其它兩個組件類沒關系 其構造函數接受一個long型參數expected_count用于進度顯示的基數 另一個構造函數progress_display(unsigned long expected_count,std::ostream&os,const std::string&s1="\n", const std::string& s2="",const std::string & s3="");三個字符串參數定義顯示三行首字符串 !!注意事項: 無法把進度的顯示輸出和程序的輸出分離這是因為progress_display和所有C++程序一樣都向標準輸出(cout)輸出字符如果使用progress_display的程序也有輸出操作那進度條將 一片混亂一個可能但遠非完美的方法就是每次顯示進度是調用restart()重新顯示進度然后用operator+=來指定當前進度
include<boost\progress.hpp>
include<string>
include<fstream>
include<vector>
using namespace std; int main() { vector<string>v(100,"a"); ofstream fs("G:\test.txt"); boost::progress_display pd(v.size(),std::cout,"\n","","");//后三個參數提供默認參數 vector<string>::iterator itpos; for (itpos = v.begin(); itpos != v.end(); ++itpos) { fs << itpos << endl; ++pd; _sleep(100); } } */ //---------------------------------date_time庫的概述
/*非常全面的日期時間庫 date_time 庫使用枚舉special_values定義特殊的時間概念位于命名空間: pos_infin ---表示正無限 neg_infin------表示負無限 not_a_date_time-------無效時間 min_data_time------表示的最小日期1400-01-01 max_data_time--------最大日期9999-12-31 日期的處理: date是date_time庫處理的核心類使用32位整數作為內部存儲,可拷貝傳值,比較操作,流輸入輸出 使用: date d1;///一個無效的日期對象 date d2(2010,1,1)數字構造日期 date d3(2000,Jan,1)//英文指定月份 date d4=from_string("1999-12-31") date d4(from_string(2005/1/1))//支持拷貝構造工程函數通過/或-分割 date d3=from_undelimted_string("20011112")//支持無分割符的純字符串 day_lock是無級別時鐘他是一個工程類調用他的靜態成員函數local_day()或universal_day()會返回當天日期對象分別是本地時期和utc日期 date 的5個is_xxx()函數用于檢測日期是否是個特殊日期 is_infinity()是否是個無限日期 is_neg_infinity()是否是個負無限日期 is_pos_infinity().......正無限日期 is_not_a_date......無效日期 is_special()......特殊日期 date很方便的轉化成字符串提供三個自由函數 to_simple_string(date d)轉換成yyy-mmm-dd mmm三字符英語月份 to_iso_string(date d) YYYMMDD to_iso_extended_string(date d)轉換成yyy-mm-dd
----------------------與tm結構的轉換: to_tm(date) date_from_tm:tm 轉化為date -----------------------日期長度 日期長度是以天為單位的時長,是度量時間長度的一個標量 基本的日期長度類是date_duration 支持全序比較操作(== != > >=)也支持遞增和遞減操作也支持除法運算但是不能除date_duration類型 乘法取余取模則不支持 date_time 庫為date_duration 定義了一個常用的typedef:day 說明了其含義一個天數的計量 為了方便計算時間長度 date_time 庫還提供了months years weeks 等另外三個時長類 / //---------------------日期運算 / date主要是與時長概念配合運算
define BOOST_DATE_TIME_SOURCE
include<boost\date_time\gregorian\gregorian.hpp>
using namespace boost::gregorian; int main() { date d1(2000, 1, 1); date d2(2008, 8, 8); std::cout << d2 - d1 << std::endl; d1 += days(10); d1 += months(2); d1 -= weeks(1); d2 -= years(2); } / //-----------------------日期區間及其運算 / date_time 庫使用date_period類表示日期區間的概念是時間軸上的一個左閉右開的區間端點為兩個date對象 構造: date_period pd1(date(2010,1,1),days(20)); 成員函數shift()和函數expand()可以變動區間:shift()將日期區間平移n天而長度不變expend()將日期向兩端延長n天 / //----------------------日期迭代器 / date_iterator,week_iterator,month_iterator,和year_iterator,分別以天周月年單位遞增和遞減 date d(2006,1,1); day_iterator d_iter(d);//默認增減步長為1; ++diter; year_iterator y_iter(*d_iter,3);遞增為3年
/ //--------------------------其它功能 / 類boost::gregorian::gregorian_calendar 提供了格里高利利的一些操作函數基本上他被date類內部使用,他的幾個靜態函數 is_leap_year()可以判斷是否是閏年end_of_month_day(),返回該月最后一天 / //------------------------------------------------------處理時間 / date_time 庫在格里高利歷的基礎上提供了微秒級的時間系統對那如果需要它最高可達到納秒級的精確度 date_time庫的時間功能位于名字空間boos::posix_time 使用范方式:#include<boost/date_time/posix_time/posix_time.hpp> using namespace boost::posix_time ----------------------------------------------時間長度 date_time庫使用time_duration度量時間的長度 精確到微秒,如果在頭文件<boost/date_time/posix_time/posix_time.hpp>之前定義了宏 BOOST_DATE_TIME_STD_CONFIG 則可以精確到納秒級 time_duration 也有幾個子類可以度量不同的時間分辨率如 hour .................等 ---------------------------------------------操作時間長度 time_duration 可以再構造函數指定時分秒和微秒來構造 time_duration td(1,20,30,1000); 使用time_duration 的子類可以更直觀的創建時間長度 hour h(1); minutes m(10); time_duration td=h+m; 使用工廠函數duration_from_string可以從一個字符串創建 time_duration td=duration_from_string("1:10:30:001"); 如果想要得到time_duration 對象字符串表示可以使用自由函數 to_simple_string(time_duration) / //--------------------------------------------時間長度的精確度 / date_time 庫默認時間的精確度是微秒納秒相關的類和函數如nanosec 和成員函數nanoseconds(),total_nanoseconds()都不可用,秒一下時間的度量都使用微秒 如使用了宏BOOST_DATE_TIME_POSIX_STD-CONFIG時time_duration 的一些行為將發生變化時間分辨率將到達納秒,構造函數中秒以下的時間獨狼都是用微秒 BOOST_DATE_TIME_POSIX_STD-CONFIG//定義納秒級宏
define BOOST_DATE_TIME_SOURCE
include<boost\date_time\posix_time/posix_time.hpp>
time_duration td(1,10,30,1000);//1000納秒 cout<<td; assert(td.total_milliseconds()==td.total_seconds()*1000); time_duration 提供靜態成員函數resolution()和num_fractional_digits()來檢測當前的精確度 ----------------------------------------------時間點 ptime是date_time庫處理時間的核心類用64位或96位的整數字內部存儲時間數據 --------------------------------------創建時間點對象 using namespace boost::gregorian; ptime p(date(2010,3,5),hours(1)); ptime p1=time_from_string("2010-3-5 01:00:00")//使用工廠函數創建 ptime p2=from_iso_string("20100305T010000") ptime有時鐘類可以從時鐘產生當前時間,時間具有不同的分辨率有兩個類second_time()和microsec_clock分別提供秒級和微秒級的分辨率 local_time 獲取當地時間 univeral_time()獲取utc當前時間 ptime p1=second_clock::local_time();//秒級精度 microsec_clock::universal_time()//微秒級精度 ptime使用 date()和time_of_day()兩個成員函數獲取時間點中的日期和時間長度 time提供三個自由函數轉化為字符串 to_simple_string(ptime):yyyy-mmm-dd hh:mm:ss.fffffff格式 to_iso_string(ptime):轉化為yyyymmddthhmmss,fffff格式 to_sio_extended_string(ptime):yyyy-mm-ddthh:mm:ss,ffffff ----------------tm,time_t等結構的轉換 to_tm(),ptime可以單向轉化為tm結構,轉化規則是:date和time_duration的組合 ptime p(date(2010,2,14),hours(20)); tm t=to_tm(p); !!!不存在從tm轉化為ptime的函數 如果要轉化需先轉化為date對象(date_from_tm()函數)得到date對象 然后手工操作tm結構得到time_duration對象,然后創建ptime from_time_t(time_t)和from_ftime<ptime>(FILETIME),他們可以從time_t和FILETIME結構創建出ptime對象,這種轉化也是單向的 ----------------時間區間 與日期區間date_period 對應,date_time庫也有時間區間的概念,使用類:time_period 其用法基本上和date_period 基本相同 ---------------時間迭代器 不同于日期迭代器,時間迭代器只有一個time_iterator.它的構造時傳入一個起始時間點ptime對象和一個不長time_duration對象 time_iterator也可日期時間以直接與ptime比較無需再使用解引用操作符 --------------格式化時間 date_time庫默認的日期時間格式簡單標準且是英文,但并不是不可改變的date_time庫提供專門的格式化對象date_facet,time_facet等來搭配io流定制 日期時間的表現形式 ------------------本地時間 date_time庫使用time_zone_base,posix_time_zone,custom_time_zone,local_date_time 等類和一個文本格式好的時區數據庫解決本地時間 -------------------序列化 date_time庫可以使用boost.serialization庫的能力是信啊數據序列化把日期時間數據存入某個文件,之后在任意的時刻讀取恢復</pre>