boost時間處理

date_time庫的時間功能位於名字空間boost::posix_time,它提供了微妙級別(最高可達納秒)的時間系統,使用需要包含頭文件"boost\date_time\posix_time\posix_time.hpp"。
1、時間長度類time_duration

類似日期長度類date_duration有days、weeks、months、years這些常用類,time_duration也有幾個子類:hours、minutes、seconds、millisec、microsec、nanosec,他們都支持流輸入輸出、比較操作、加減乘除運算。

//對象的定義
    boost::posix_time::time_duration td(1, 10, 30, 1000); //1小時10分鐘30秒1毫秒
    boost::posix_time::time_duration  td1(1, 60, 60, 1000); //2小時1分鐘1毫秒,超出的時間會自動進位
    boost::posix_time::time_duration td2 = boost::posix_time::duration_from_string("1:10:30:001");  //1小時10分鐘30秒1毫秒

    //成員函數
    assert(td.hours() == 1 && td.minutes() == 10 && td.seconds() == 30);
    assert(td.total_seconds() == 1 * 3600 + 10 * 60 + 30);
    
    //獲取字符串表示
    cout << boost::posix_time::to_simple_string(td) << endl; //輸出爲 01:10:30.001000
    cout << boost::posix_time::to_iso_string(td) << endl; //輸出爲 011030.001000

    //運算
    boost::posix_time::hours h(1);
    boost::posix_time::minutes m(10);
    boost::posix_time::seconds s(30);
    boost::posix_time::millisec ms(1);
    boost::posix_time::time_duration td3 = h + m + s + ms;
    assert(td2 == td3);

2、時間點ptime

創建ptime的方法是在其構造函數傳入一個date和一個time_duration,不傳入time_duration的話爲0點,ptime支持流輸入輸出、比較操作、減法運算、與date_duration、time_duration的加減運算:

//對象的定義
    boost::posix_time::ptime p(boost::gregorian::date(2010, 3, 5)); //2010年3月5號0點
    boost::posix_time::ptime p1(boost::gregorian::date(2010, 3, 5), boost::posix_time::hours(1)); //2010年3月5號1點
    boost::posix_time::ptime p2 = boost::posix_time::time_from_string("2010-3-5 01:00:00");
    boost::posix_time::ptime p3 = boost::posix_time::from_iso_string("20100505T010000");

    //獲取當前時間
    boost::posix_time::ptime p4 = boost::posix_time::second_clock::local_time(); //本地時間,秒精度
    cout << p4 << endl; //可以直接輸出ptime,2018-Apr-11 16:23:54
    //boost::posix_time::ptime p4 = boost::posix_time::microsec_clock::local_time(); //本地時間,微妙精度,2018-Apr-11 08:23:54.986535
    //boost::posix_time::ptime p4 = boost::posix_time::second_clock::universal_time(); //UTC時間,微妙精度

    //獲取字符串表示
    cout << boost::posix_time::to_iso_extended_string(p) << endl; //輸出爲2010-03-05T00:00:00
    cout << boost::posix_time::to_iso_string(p) << endl; //輸出爲20100305T000000
    cout << boost::posix_time::to_simple_string(p) << endl; //輸出爲2010-Mar-05 00:00:00

ptime相當於date + time_duration,所以對於它的操作可以分解爲對這兩個部分的操作,可以通過兩個成員函數date()和time_of_day()獲得日期和時間段,然後分別處理,如:

boost::posix_time::ptime p4(boost::gregorian::date(2010, 3, 20), boost::posix_time::hours(12) + boost::posix_time::minutes(30));
    boost::gregorian::date d = p4.date(); //獲取date
    boost::posix_time::time_duration td4 = p4.time_of_day(); //獲取time_duration

    assert(d.month() == 3 && d.day() == 20);
    assert(td4.total_seconds() == 12 * 3600 + 30 * 60);

    boost::posix_time::ptime p5 = p4 + boost::posix_time::hours(3);
    assert(p4 < p5);
    assert(p5 - p4 == boost::posix_time::hours(3));
    p5 += boost::gregorian::months(1);
    
    boost::posix_time::ptime pTime = boost::posix_time::second_clock::local_time();
    std::string strDate = boost::gregorian::to_iso_extended_string(pTime.date()); // 當前日期:2019-03-06
    std::string strTimeOfDay = boost::posix_time::to_simple_string(pTime.time_of_day()); // 當前時間:15:03:55
    std::string strTime = strDate + ", " + strTimeOfDay; // 當前日期和時間:2019-03-06, 15:03:55

boost::posix_time::to_tm()可以由ptime轉換爲tm,如果想要把tm轉換爲ptime,可以使用boost::gregorian::date_from_tm()得到date對象,然後再根據tm得到time_duration對象,最後通過date和time_duration創建出ptime。

boost::posix_time::to_time_t()可以由ptime轉換爲time_t,boost::posix_time::from_time_t()可以由time_t轉換爲ptime,但這兩個函數是以UTC時間爲標準的,使用的話還需要進行時區轉換。

不同於日期迭代器,時間迭代器只有一個time_iterator,在它的構造函數中傳入一個起始時間ptime和一個步長time_duration,

boost::posix_time::ptime p6(boost::gregorian::date(2010, 2, 27), boost::posix_time::hours(10));
    boost::posix_time::time_iterator t_iter(p6, boost::posix_time::minutes(20));
    for (; t_iter < p6 + boost::posix_time::hours(1); ++t_iter)
    {
        cout << *t_iter << endl;
    }
    //輸出爲:
    //2010 - Feb - 27 10:00 : 00
    //2010 - Feb - 27 10 : 20 : 00
    //2010 - Feb - 27 10 : 40 : 00

3、高精度的timer

boost::timer的精度只有毫秒,利用date_time庫可以實現一個微妙級別的計時器:

#include "boost\date_time\posix_time\posix_time.hpp"

template<typename Clock = boost::posix_time::microsec_clock>
class basic_ptimer
{
public:
    basic_ptimer() { restart(); }
    virtual ~basic_ptimer(){}
public:
    void restart() { _start_time = Clock::local_time(); }
    double elapsed() { return (Clock::local_time() - _start_time).total_microseconds() / (double)(1000 * 1000); } //以秒爲單位,精度爲微秒
    string elapsed_s() { return boost::posix_time::to_simple_string(Clock::local_time() - _start_time); } //格式爲hh:mm:ss.ffffff,精度爲微秒
private:
    boost::posix_time::ptime _start_time;
};
typedef basic_ptimer<> ptimer;


int main()
{
    ptimer p2;
    Sleep(1000);
    printf("%.6f\n", p2.elapsed()); //輸出爲1.001057
    //cout << p2.elapsed_s() << endl; //輸出爲00:00:01.001057
}

4、不同時區的本地時間

使用本地時間類local_date_time及boost提供的一個文本格式的時區數據庫(位於libs/date_time/data/下)可以獲得不同時區的本地時間,本地時間功能位於名字空間boost::local_time中,使用本地時間功能需要包含頭文件"boost\date_time\local_time\local_time.hpp"。

下面假設飛機從北京2008年1月7號12點整飛往紐約,飛行時間爲15個小時,輸出飛行到紐約後的本地時間:

#include "boost\date_time\posix_time\posix_time.hpp"
#include "boost\date_time\gregorian\gregorian.hpp"
#include "boost\date_time\local_time\local_time.hpp"

int main()
{
    boost::local_time::tz_database tz_db;
    tz_db.load_from_file("./date_time_zonespec.csv"); //假設文本數據庫位於當前目錄
    boost::local_time::time_zone_ptr shz = tz_db.time_zone_from_region("Asia/Shanghai"); //獲得上海時區,即北京時間
    boost::local_time::time_zone_ptr nyz = tz_db.time_zone_from_region("America/New_York"); //獲得紐約時區

    //獲得北京當地時間
    boost::local_time::local_date_time dt_bj(boost::gregorian::date(2008, 1, 7), 
                                                                    boost::posix_time::hours(12), 
                                                                    shz, 
                                                                    shz->has_dst());//是否夏令時
    cout << dt_bj << endl; //飛機起飛時北京時間

    dt_bj += boost::posix_time::hours(15); //飛機飛行了15小時
    cout << dt_bj << endl; //飛機到達紐約後的北京時間

    boost::local_time::local_date_time dt_ny = dt_bj.local_time_in(nyz); //由北京時間獲得紐約當地時間
    cout << dt_ny << endl; //飛機到達紐約後的紐約時間
    
    return 0;
}

ptime的幾種構造方法:

// 1. 常規的構造函數有如下幾種:
	ptime p0;
	// 最常用的構造方法
	ptime p1(date(2012, 11, 30), time_duration(1, 2, 3));	// 2012-Nov-30 01:02:03
	ptime p2(p1);											// 複製構造
	ptime ps1(neg_infin);
	ptime ps2(pos_infin);
	ptime ps3(not_a_date_time);
	ptime ps4(max_date_time);	// 9999-Dec-31
	ptime ps5(min_date_time);	// 1400-Jan-01

    // 2. 通過字符串構造
	ptime pstr1(time_from_string("2012-11-30 23:59:59.000"));
	ptime pstr2(from_iso_string("20121130T200001"));
 
	// 3. 通過clock構造
	ptime pc1(second_clock::local_time());
	ptime pc2(second_clock::universal_time());
	ptime pc3(microsec_clock::local_time());
	ptime pc4(microsec_clock::universal_time());
 
	// 4. 通過轉換函數from_time_t和ptime_from_tm, 
	// 注意: 這樣通過from_time_t轉換成ptime後, 好像是格林威治時間
	time_t t1 = time(NULL);
	ptime pc5 = from_time_t(t1);
	std::cout << pc5 << std::endl;
 
	tm* t2 = localtime(&t1);
	ptime pc6 = ptime_from_tm(*t2);
	std::cout << pc6 << std::endl;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章