Boost之日期時間處理(date_time庫)
阿新 • • 發佈:2018-12-22
概述
使用date_time庫需要在編譯時加上"-lboost_date_time",而且需要包含以下標頭檔案: 處理日期的元件:#include <boost/date_time/gregorian/gregorian.hpp> 處理時間的元件:#include <boost/date_time/posix_time/posix_time.hpp>date類
date是date_time庫處理日期的核心類,使用一個32位的整數作為內部儲存,以天為單位表示時間點概念。date也全面支援比較操作和輸入輸入出,我們可以完全把它當成一個像int、string那樣的基本型別來使用。#include <iostream> #include <boost/date_time/gregorian/gregorian.hpp> using namespace std; using namespace boost::gregorian; int main() { date d1(2001, 1, 1); date d2(2002, Feb, 2); date d3 = from_string("2003-3-3"); date d4 = from_string("2004/4/4"); date d5 = from_undelimited_string("20050505"); cout << "本地日期:" << day_clock::local_day() << endl << "UTC日期:" << day_clock::universal_day() << endl << endl; cout << "負無限日期:" << neg_infin << endl << "正無限日期:" << pos_infin << endl << "無效日期:" << not_a_date_time << endl << "最大可能日期:" << max_date_time << endl << "最小可能日期:" << min_date_time << endl << endl; cout << "對於2001-01-01:" << endl << "年:" << d1.year() << endl << "月:" << d1.month() << endl << "日:" << d1.day() << endl << endl; cout << "對於2002-02-02:" << endl << "星期數:(0表示星期天)" << d2.day_of_week() << endl << "當年的第幾天:" << d2.day_of_year() << endl << "當年的第幾周:" << d2.week_number() << endl << "當月的最後一天:" << d2.end_of_month() << endl << endl; cout << "對於2003-03-03:" << endl << "直接列印日期:" << d3 << endl << "使用to_simple_string列印日期:" << to_simple_string(d3) << endl << "使用to_iso_string列印日期:" << to_iso_string(d3) << endl << "使用to_iso_extended_string列印日期:" << to_iso_extended_string(d3) << endl << endl; return 0; }
輸出: 本地日期:2016-Jun-24
UTC日期:2016-Jun-24
負無限日期:1
正無限日期:2
無效日期:0
最大可能日期:4
最小可能日期:3
對於2001-01-01:
年:2001
月:Jan
日:1
對於2002-02-02:
星期數:(0表示星期天)Sat
當年的第幾天:33
當年的第幾周:5
當月的最後一天:2002-Feb-28
對於2003-03-03:
直接列印日期:2003-Mar-03
使用to_simple_string列印日期:2003-Mar-03
使用to_iso_string列印日期:20030303
使用to_iso_extended_string列印日期:2003-03-03
date_duration類
date_duration表示日期長度,是以天為單位的時長,值可以是任意的整數,可正可負。date_time庫為date_duration定義了一個常用的typedef: days。此外,date_time庫還提供了months、years、weeks等另外三個時長類,分別用來表示月,年和星期,它們的含義與days型別,但行為不太相同。輸出: dd1 + dd2 = 5<span style="font-family:SimSun;">#include <iostream> #include <boost/date_time/gregorian/gregorian.hpp> using namespace std; using namespace boost::gregorian; int main() { days dd1(10), dd2(-5); cout << "dd1 + dd2 = " << (dd1 + dd2).days() << endl; weeks w(3); cout << "3個星期的天數:" << w.days() << endl; months m(5); years y(3); months m2 = y + m; cout << "3年5個月的月數:" << m2.number_of_months() << endl << endl; date d1(2001, 1, 1); date d2(2002, 1, 1); cout << "d2 - d1 = " << d2 - d1 << endl; d1 += days(10); cout << "d1 + days(10)後:" << d1 << endl; d1 += months(2); cout << "d1 + months(2)後:" << d1 << endl; d1 -= weeks(1); cout << "d1 - weeks(1)後:" << d1 << endl; d1 -= years(10); cout << "d1 - years(10)後:" << d1 << endl; return 0; }</span>
3個星期的天數:21
3年5個月的月數:41
d2 - d1 = 365
d1 + days(10)後:2001-Jan-11
d1 + months(2)後:2001-Mar-11
d1 - weeks(1)後:2001-Mar-04
d1 - years(10)後:1991-Mar-04
date_period類
date_period類用來表示日期區間的概念,它是時間軸上一個左閉右開區間,端點是兩個date物件#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace std;
using namespace boost::gregorian;
int main()
{
/* 兩種構造方式 */
date_period dp1(date(2000, 1, 1), days(20));
date_period dp2(date(2000, 1, 5), date(2000, 1, 15));
/*
* 成員函式begin()和last()返回日期區間的兩個端點
* end()返回last()後的第一天,與標準容器中的end()含義相同
* length()返回日期區間的長度
*/
cout << "dp1.begin() = " << dp1.begin() << endl
<< "dp1.last() = " << dp1.last() << endl
<< "dp1.end() = " << dp1.end() << endl
<< "dp1.length() = " << dp1.length() << endl << endl;
/*
* shift()將日期區間平移n天而長度不變
* expand()將日期區間向兩端延伸n天,相當於區間長度加2n天
*/
dp1.shift(days(3));
cout << "shitf(): " << dp1 << endl;
dp1.expand(days(3));
cout << "expand(): " << dp1 << endl << endl;
/* 判斷某個日期是否在區間內或者計算日期區間的交集 */
if (dp1.is_after(date(1999, 12, 12)))
cout << "dp1在1999-12-12後\n";
if (dp1.is_before(date(2000, 1, 27)))
cout << "dp1在2000-01-20前\n";
if (dp1.contains(date(2000, 1, 10)))
cout << "2000-01-10在dp1中\n";
if (dp1.contains(dp2))
cout << "dp1包含dp2\n";
if (dp1.intersects(dp2))
cout << "dp1和dp2存在交集,交集為:"
<< dp1.intersection(dp2) << endl;
if (!dp1.is_adjacent(dp2))
cout << "dp1和dp2不相鄰\n\n";
/*
* merge()返回兩個區間的並集,如果區間無交集或者不相鄰則返回無效區間
* span()合併兩日期區間及兩者的間隔,相當於廣義的merge()
*/
date_period dp3(date(2000, 2, 1), days(10));
cout << "dp1.merge(dp3): " << dp1.merge(dp3) << endl
<< "dp1.span(dp3): " << dp1.span(dp3) << endl;
return 0;
}
輸出:
dp1.begin() = 2000-Jan-01dp1.last() = 2000-Jan-20
dp1.end() = 2000-Jan-21
dp1.length() = 20
shitf(): [2000-Jan-04/2000-Jan-23]
expand(): [2000-Jan-01/2000-Jan-26]
dp1在1999-12-12後
dp1在2000-01-20前
2000-01-10在dp1中
dp1包含dp2
dp1和dp2存在交集,交集為:[2000-Jan-05/2000-Jan-14]
dp1和dp2不相鄰
dp1.merge(dp3): [2000-Jan-01/1999-Dec-31]
dp1.span(dp3): [2000-Jan-01/2000-Feb-10]
日期迭代器
通過日期迭代器可以用簡單的遞增遞減操作符連續訪問日期,這些迭代器包括:day_iterator、week_iterator、month_iterator和year_iterator。需要注意的是它們並不符合標準迭代器的定義,沒有difference_type、pointer、reference等內部型別定義,不能使用std::advance()或者operator+=來前進或者後退。#include <iostream>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace std;
using namespace boost::gregorian;
int main()
{
date d(2000, 1, 1);
day_iterator d_iter(d); //增減步長預設為1天
++d_iter;
if (d_iter == date(2000, 1, 2)) //這裡不需要解引用就可以直接比較
cout << "d_iter == date(2000, 1, 2)\n";
year_iterator y_iter(*d_iter, 8); //增減步長為8年
++y_iter;
if (y_iter->year() == 2008)
cout << "增長了8年\n";
return 0;
}
輸出: d_iter == date(2000, 1, 2)
增長了8年
time_duration類
與date_duration類似,date_time庫使用time_duration度量時間長度。time_duration有幾個子類,可以度量不同的時間解析度,它們分別是:hours、minutes、seconds、millisec/millisecnods、microsec/microseconds和nanosec/nanoseconds。#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
using namespace boost::posix_time;
int main()
{
/* 1小時10分鐘30秒1毫秒 */
time_duration td1 = duration_from_string("1:10:30:001");
cout << "td1: " << td1 << endl;
/* 子類 */
hours h(1);
minutes m(10);
seconds s(30);
millisec ms(1);
time_duration td2 = h + m + s + ms;
cout << "td2: " << td2 << endl
<< "hours: " << td2.hours() << endl
<< "minutes: " << td2.minutes() << endl
<< "total_seconds: " << td2.total_seconds() << endl
<< "total_milliseconds: " << td2.total_milliseconds() << endl;
/* 字串表示 */
cout << "to_simple_string: " << to_simple_string(td2) << endl; //01:10:30.001000
cout << "to_iso_string: " << to_iso_string(td2) << endl; //011030.001000
return 0;
}
輸出:
td1: 01:10:30.001000td2: 01:10:30.001000
hours: 1
minutes: 10
total_seconds: 4230
total_milliseconds: 4230001
to_simple_string: 01:10:30.001000
to_iso_string: 011030.001000
ptime類
ptime類表示時間點,它相當於一個日期再加上一個小於一天的時間長度。#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace std;
using namespace boost::posix_time;
using namespace boost::gregorian;
int main()
{
ptime p1(date(2001, 1, 1), hours(1)); //2001年1月1日凌晨1時
ptime p2 = time_from_string("2002-2-2 02:00:00");
ptime p3 = from_iso_string("20030303T030000"); //日期與時間用字母T隔開
ptime p4 = second_clock::local_time(); //本地當前時間,秒精度
ptime p5 = microsec_clock::universal_time(); //UTC當前時間,微秒精度
cout << p1 << endl
<< p2 << endl
<< p3 << endl
<< p4 << endl
<< p5 << endl << endl;
/*
* date()獲得時間點中的日期
* time_of_day()獲得時間長度
*/
date d = p1.date();
time_duration td = p1.time_of_day();
cout << d << ", " << td << endl << endl;
cout << to_simple_string(p2) << endl //轉換為YYYY-mmm-DD HH:MM:SS.ffffff
<< to_iso_string(p2) << endl //轉換為YYYYMMDDTHHMMSS,ffffff
<< to_iso_extended_string(p2) << endl; //轉換為YYYY-MM-DDTHH:MM:SS,ffffff
return 0;
}
輸出:
2001-Jan-01 01:00:002002-Feb-02 02:00:00
2003-Mar-03 03:00:00
2016-Jun-26 15:35:23
2016-Jun-26 07:35:23.240536
2001-Jan-01, 01:00:00
2002-Feb-02 02:00:00
20020202T020000
2002-02-02T02:00:00
time_period類
與日期區間date_period對應,date_time庫也有時間區間的概念,類time_period使用ptime作為區間的兩個端點,同樣是左閉右開區間,它與date_period用法基本相同。
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace std;
using namespace boost::posix_time;
using namespace boost::gregorian;
int main()
{
ptime p(date(2014,1,1),hours(12)) ;
time_period tp1(p, hours(8)); //一個8小時的區間
time_period tp2(p + hours(8), hours(1)); //1小時的區間
if (tp1.end() == tp2.begin() && tp1.is_adjacent(tp2))
cout << "兩個區間相鄰\n";
if (!tp1.intersects(tp2))
cout << "兩個區間不相交\n";
tp1.shift(hours(1)); //平移1小時
if (tp1.is_after(p))
cout << "tp1在中午之後\n";
if (tp1.intersects(tp2))
cout << "兩個區間現在相交\n";
tp2.expand(hours(10)); //向兩端擴充套件10小時
if (tp2.contains(p) && tp2.contains(tp1))
cout << "tp2包含p且包含tp1\n";
return 0;
}
輸出:
兩個區間相鄰兩個區間不相交
tp1在中午之後
兩個區間現在相交
tp2包含p且包含tp1
時間迭代器
不同於日期迭代器,時間迭代器只有一個time_iterator。它在構造時傳入一個起始時間點ptime物件和一個步長time_duration物件,然後就同日期迭代器一樣使用前置式operator++、operator--來遞增或遞減時間,解引用操作符返回一個ptime物件。#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace std;
using namespace boost::posix_time;
using namespace boost::gregorian;
int main()
{
ptime p(date(2014,11,3),hours(10)) ;
for (time_iterator t_iter(p, minutes(10)); t_iter < p + hours(1); ++ t_iter)
cout << *t_iter << endl;
return 0;
}
輸出:
2014-Nov-03 10:00:002014-Nov-03 10:10:00
2014-Nov-03 10:20:00
2014-Nov-03 10:30:00
2014-Nov-03 10:40:00
2014-Nov-03 10:50:00