date_time 日期相关的库,是 boost 中少数需要编译的库,但是实践中,在 Linker 链接器中链接 libboost_date_time.a
即可。也就是在链接时,加上 -l(boost_date_time) 参数。
头文件
使用 date_timer 需要包含以下头文件。 diedaiqi #include <boost/date_time/gregorian/gregorian.hpp> using namespace boost::gregorian;
date基本使用
将时间想象成无线延伸的实数轴,时间点是数轴上的一个点,时间段就是区间,时长是有正负号的标量,两个时间点差,不属于数轴。时间点,时间段,时长之间可以进行运算,有些有实际意义,例如时间点+时长=时间点,时长+时长=时长,时间段交集∩时间段=时间段,时间点属于∈时间段等等,有些无意义等等。
date_time 库支持无限时间和无效时间(NADT, Not Available Date Time)。
日期基于格里高利历,支持从 1400-01-01 到 9999-12-31 之间的日期计算,不支持公元前日期,名字空间 boost::gregorian, 需要包含上文所述头文件。
构造
date 是 date_time 库处理日期的核心类,使用32位整数作为内部存储,以天位单位表示时间点概念,日期的构造方法
date d1; // 无效日期
date d2(2010,1,1);
date d3(2000, Jan, 1);
date d4(d2); // 拷贝构造
//you can compare between d1 d2 d3 d4 with == < >
也可以直接使用字符串来构造:
date d0 = from_string("1999-12-31");
date d5 ( from_string("2005/1/1") );
date d6 = from_undelimited_string("20001109");
或者直接从工厂类构造,调用 day_clock 的静态成员函数 local_day() 或者 universal_day() 返回当天的日期对象,分别是本地日期和 UTC 日期。 local_day() 依赖于操作系统时区设置。
// local date and UTC date
cout << day_clock::local_day() << endl;
cout << day_clock::universal_day() << endl;
特殊的日期:
date neg(neg_infin); //negative infinite time
date pos(pos_infin); //positive infinite time
date notdate(not_a_date_time); //not a date time
date maxdate(max_date_time); //max date
date mindate(min_date_time); //min date
cout << neg << endl << pos << endl << maxdate << endl << mindate <<endl;
date访问
date 成员函数 year(), month(), day() 返回年月日; year_month_day() 返回 date::ymd_type 结构,一次性获取年月日信息。
date nowdate = day_clock::local_day();
date::ymd_type ymd = nowdate.year_month_day();
cout << ymd.year << endl << ymd.month << endl << ymd.day << endl;
// day_of_week() return Monday, Tuesday..
// day_of_year() return number of the day in this year, max 366
// end_of_month() return the date of end of month
cout << nowdate.day_of_week() << endl;
cout << nowdate.day_of_year() << endl;
cout << nowdate.end_of_month() << endl;
day_of_week() 返回 date 星期数, 0 表示星期天; day_of_year() 返回 date 是当年第几天,最多366; end_of_month() 返回当月最后一天的 date 对象。
week_number() 返回date所在周是当年的第几个周,范围0到53. 如果年初的几天为去年的周,则周数为53,即第0周。
date 有5个 is_xxx() 函数,用于检验日期是否是一个特殊日期
- is_infinity() 是否无限日期
- is_neg_infinity() 是否负无限日期
- is_pos_infinity() 是否正无限日期
- is_not_a_date() 是否无效日期
- is_special() 是否任意一个特殊日期
date输出
date 对象转成字符串输出
date now = day_clock::local_day();
// date output
cout << to_simple_string(now) << endl; //YYYY-mmm-DD mmm English
cout << to_iso_string(now) << endl; //YYYYMMDD
cout << to_iso_extended_string(now) << endl; //YYYY-MM-DD
cout << now << endl;
支持流输入
date inputdate;
cout << "Input a date: "; // 2010-Jan-01
cin >> inputdate; //default using YYYY-mmm-DD English abbr
cout << "\nThe input date is: " << inputdate << endl;
日期长度 date_duration
日期长度类 date_duration , 天为单位,度量时间长度的标量。值为任意整数,可正可负。
成员函数 days() 返回时长天数, is_special() 和 is_negative() 可判断 date_duration 对象是否为特殊值,或者负值, unit() 返回时长最小单位,即1
date_duration 支持全序比较操作 ==, != , <, <= 等等,支持加减法,递增递减,支持除整数,其他乘法,取模,取余不支持。
date_time 库为 date_duration 定义了一个常用的 typedef:days 名字。
days dd1(10); // ten days
weeks w(2); // two weeks
months m(5); // five months
years y(2); // two years
months m2 = y + m; // two years and 5 months
日期计算
日期支持简单加减运算
// date compute
date dstart(2000,1,1), dend(2008,8,8);
cout << dend - dstart << endl; // 3142 days
dstart += days(10); // 2000-1-11
dstart += months(2); // 2000-3-11
dstart -= weeks(1); // 2000-3-4
dstart += years(4); // 2004-3-4
//something need to be noticed
date endofmonth(2010, 3, 30);
endofmonth -= months(1); //2010-2-28
endofmonth -= months(1); //2010-1-31
endofmonth += months(2); //2010-3-31
日期区间 date_period
date_period 类来表示日期区间,时间轴上是一个左闭右开区间,端点是两个date对象,左值必须小于右值。
// date period
date_period pd(dstart, dend); // (date, date)
date_period pd1(dstart, days(10)); // (date, days)
cout << pd << endl;
pd.shift(days(10)); // shift days 平移N天,长度不变
cout << pd << endl;
pd.expand(days(3)); // expand days 像两端扩展三天,长度加2n天
cout << pd << endl;
成员函数 begin() & end() 返回日期区间两个端点, end() 返回 last() 后的第一天。
date_period 可以全序比较运算,依据区间端点,即第一个区间的end() 和第二个区间的 begin(), 判断两个区间在时间轴上的位置大小。如果日期区间相交或者包含,比较操作无意义。
date_period 支持输入输出操作符,默认的输入输出格式是 YYYY-mmm-DD/YYYY-mmm-DD.
date date2014 = from_string("2014-01-01");
date nowdate = day_clock::local_day();
date_period pdl(date2014, nowdate);
date one_day_in_2015 = from_undelimited_string("20150101");
cout << pdl.contains(one_day_in_2015) << endl;
/*
* date_period
* is_before(), is_after()
* contains()
* intersects() 区间是否存在交集
* intersections() 返回两个区间的交集
* is_adjacent() 是否相邻
* merge() 返回两个区间并集,如果无交集或者不相邻则返回无效区间
* span() 合并两区间及两者间的间隔
*/
日期迭代器
/*
* date iterator
* use only ++iterator, --iterator, don't use iterator++, iterator--
*/
date d(2006,11,26);
day_iterator d_iter(d);
++d_iter;
year_iterator y_iter(d,3); // 增减步长为3年
++y_iter; // 增加3年
cout << y_iter->year();
综合运用
void print_one_month(){
date nowdate = day_clock::local_day();
date month_start(nowdate.year(), nowdate.month(), 1);
date month_end = nowdate.end_of_month();
for(day_iterator d_iter(month_start); d_iter != month_end; ++d_iter){
cout << *d_iter << " " << d_iter->day_of_week() << "\t";
if(d_iter->day_of_week() == boost::date_time::Sunday){
cout << endl;
}
}
}
/*
* input your birthday and years after that output the day of
* future birthday
*/
void birthday_week(){
date birthday(1992, 06, 05);
years y30(30);
date future_birthday = birthday + y30;
cout << future_birthday.day_of_week() << endl;
}
/*
* printout the days passed since you were born.
*/
void days_passed(){
date birthday(1990, 10, 8);
date nowdate = day_clock::local_day();
cout << "Since you were born, there were " << nowdate - birthday << " days passed!"<< endl;
}
时间长度 time_duration
度量基本小时、分钟和秒钟,秒以下精确到微秒。
time_duration 有子类,度量不同时间分辨率,分别是: hours,minutes,seconds,millisec/milliseconds,microsec/microseconds和nanosec/nanoseconds。
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
// 2 h 01 m 06.001 s
time_duration td(1, 60, 60, 1000*1000*6 + 1000);
hours h(1); // one hour
minutes m(10);
seconds s(30);
millisec ms(1);
time_duration td1 = h + m + s + ms;
time_duration td2 = duration_from_string("1:10:30:001");
cout << td2 << endl; // 01:10:30.001000
cout << to_simple_string(td1) << endl;
cout << to_iso_string(td2) << endl;
时间点 ptime
构造函数中同时指定date和time_duration对象,ptime等于一个日期加上当天的时间偏移,轻量级对象,可以被高效的任意拷贝和赋值,支持全序比较和加减运算。
using namespace boost::gregorian;
ptime p(date(2010,3,5), hours(1));
ptime p1 = time_from_string("2012-09-11 09:09:09");
cout << p1 << endl;
ptime p2 = from_iso_string("20100909T011001");
cout << p2 << endl;
ptime nowtime = second_clock::local_time(); // second accurate
ptime nowtime2 = microsec_clock::universal_time(); // milli second accurate
ptime pnot(not_a_date_time);
ptime pinf(pos_infin);
cout << to_simple_string(nowtime) << endl;
cout << to_iso_string(nowtime) << endl;
cout << to_iso_extended_string(nowtime) << endl;
时间区间 time_period
time_period tp1(nowtime, hours(8)); // start from nowtime, last for eight hours
tp1.shift(hours(2));
tp1.expand(hours(1));
时间迭代器和日期迭代器,时间迭代器需要时间点和时间长度来构造。
ptime p(day_clock::local_day(),hours(10));
for (time_iterator t_iter(p, minutes(10)); t_iter < p+hours(1); ++ t_iter) {
cout << *t_iter << endl;
}