//"Boost_data_Timer.h"头文件 #ifndef BOOST_TEST #define BOOST_DATE_TIME_SOURCE #include <libs/date_time/src/gregorian/greg_names.hpp> #include <libs/date_time/src/gregorian/date_generators.cpp> #include <libs/date_time/src/gregorian/greg_month.cpp> #include <libs/date_time/src/gregorian/greg_weekday.cpp> #include <libs/date_time/src/gregorian/gregorian_types.cpp> //#include "boost/date_time/gregorian/conversion.hpp" #include "boost/date_time/gregorian/gregorian.hpp" //date_time库的时间功能位于名字空间boost::posix_time,为了使用时间组件,需要 //包含头文件<boost/date_time/posix_time/posix_time.hpp>即 #include <boost/date_time/posix_time/posix_time.hpp> using namespace boost::posix_time; #endif // !BOOST_TEST
//"Boost_data_Timer.cpp" #include <iostream> #include <cassert> //#include <Windows.h> //#include <windef.h> #include "Boost_data_Timer.h" using namespace boost; using namespace std; //使用date_time日期功能需要包含gregorian.hpp,并声明命名空间。 using namespace boost::gregorian; //日期处理测试示例 bool test_date_time() { //date赋值的几种方式 date d1; date d2(2010, 1, 1); date d3(2000, Jan, 1); date d4(d2); //从字符串产生赋值 { date dd1 = from_string("1999-12-31"); date dd2 = from_string("2005/1/1"); date dd3 = from_undelimited_string("20000101"); //枚举类型特殊时间,超出范围值会报异常。 date ddd1(neg_infin); //负无限日期 date ddd2(pos_infin); //正无限日期 date ddd3(not_a_date_time); //无效日期 date ddd4(max_date_time);//最大可能日期9999-12031 :)万年虫有没有? date ddd5(min_date_time);//最小可能日期1400-01-01 assert(d1 == date(not_a_date_time)); assert(d2 == d4); assert(d3 < d4); } //auto类型转换时的测试 if (d2.is_infinity()) //是否为一个无限日期 { auto y = d2.year(); auto m = d2.month(); auto d = d2.day(); cout << y << endl; cout << m << endl; cout << d << endl; cout << d2.year() << endl; } date::ymd_type ymd = d2.year_month_day(); if (ymd.day) { auto y = ymd.year; auto m = ymd.month; auto d = ymd.day; cout << y << endl; cout << m << endl; cout << d << endl; //测试auto类型转换 int a = y; cout << a << endl; //直接输出ymd cout << ymd.year << ymd.month << ymd.day << endl; } { //day_of_week星期数 date dd2(2010, 01, 01), dd3(2011, 12, 12); auto a = dd2.day_of_week(); cout << "dd2.day_of_week: " << dd2.day_of_week() << endl; //day_of_year当年的第几天 cout << "dd2.day_of_year:" << dd2.day_of_year() << endl; //end_of_month返回当月最后一天date对象 auto b = dd2.end_of_month(); cout << b.year() << b.month() << b.day() << endl; cout << "dd2.end_of_month:" << b.day() << endl; //week_number 返回date所在的周是当年的第几周范围0-53 cout << "week_number: " << dd3.week_number() << endl; } //is_xxxx相关函数测试 { //is_infinity() 是否是一个无限日期 //is_neg_infinity() 是否是一个负无限日期 //is_pos_infinity() 是否是一个正无限日期 //is_not_a_date() 是否是一个无效日期 //is_special() 是否是任意一个特殊日期 assert(date(pos_infin).is_infinity()); assert(date(pos_infin).is_pos_infinity()); assert(date(neg_infin).is_neg_infinity()); assert(date(not_a_date_time).is_not_a_date()); assert(date(not_a_date_time).is_special()); assert(!date(2010, 10, 1).is_special()); } //date输出相关示例 { date d(2008, 11, 20); //YYYY-MMM-DD cout << to_simple_string(d) << endl; //YYYYMMDD cout << to_iso_string(d) << endl; //YYYY-MM-DD cout << to_iso_extended_string(d) << endl; //直接出输d cout << d << endl; } //date与tm的相互转换 { date d(2010, 2, 1); //to_tm需要引入" #include "boost/date_time/gregorian/gregorian.hpp" //date转tm tm t = to_tm(d); assert(t.tm_hour == 0 && t.tm_min == 0); assert(t.tm_year == 110 && t.tm_mday == 1); //tm转date date d2 = date_from_tm(t); assert(d == d2); } //days(date_duration)用法的代码如下: { days dd1(10), dd2(-100), dd3(255); assert(dd1 > dd2&&dd1 < dd3); assert(dd1 + dd2 == days(-90)); assert((dd1 + dd3).days() == 265); assert(dd3 / 5 == days(51)); } //months,years,weeks时长类 { //三个星期 weeks w(3); assert(w.days() == 21); //5个月 months m(5); //2年 years y(2); //加法运算m2=2年零5个月 months m2 = y + m; assert(m2.number_of_months() == 29); assert((y * 2).number_of_years() == 4); cout << m2.number_of_months() << endl; cout << y.number_of_years() << endl; cout << w << endl; } //计算2000年1月1日到2008年8月8日的天数等。 { date d1(2000, 1, 1), d2(2008, 8, 8); cout << d2 - d1 << endl; //3142天 assert(d1 + (d2 - d1) == d2); d1 += days(10); //2000-1-11 assert(d1.day() == 11); d1 += months(2); //2000-3-11 assert(d1.month() == 3 && d1.day() == 11); d1 -= weeks(1); //2000-3-4 assert(d1.day() == 4); assert(d1.year() == 2000); cout << d1 << endl; d2 -= years(7); //2001-8-8 assert(d2.year() == d1.year() + 1); } //特殊日期的运算 { date d1(2010, 1, 1); date d2(d2.is_pos_infinity()); d2 = d1 + days(not_a_date_time); assert(d2.is_not_a_date()); d2 = date(neg_infin); days dd = d1 - d2; assert(dd.is_special() && !dd.is_negative()); } //月末操作 { date d(2010, 3, 30); d -= months(1); //2010-2-28变为月末,原30的日期信息丢失 d -= months(1); //2010-1-31 d += months(2); //2010-30-31 assert(d.day() == 31); //与原来日期不相等 } // 日期区间date_period { date_period dp(date(2010, 1, 1), days(20)); assert(!dp.is_null()); assert(dp.begin().day() == 1); assert(dp.last().day() == 20); assert(dp.end().day() == 21); assert(dp.length().days() == 20); //date_period输出形式 date_period dp1(date(2010, 1, 1), days(20)); date_period dp2(date(2010, 2, 19), days(10)); cout << dp1 << endl; cout << dp2 << endl; assert(dp1 < dp2); } //date_period日期区间的运算 { date_period dp(date(2010, 1, 1), days(20)); dp.shift(days(3)); assert(dp.begin().day() == 4); assert(dp.length().days() == 20); cout << dp << endl; dp.expand(days(3)); assert(dp.begin().day() == 1); assert(dp.length().days() == 26); cout << dp << endl; } //date_period成员函数判断某个日期是否在区间内,或者计算日期区间的交集 { //is_before()、is_after(); 日期区间是否在日期前或后; //contains() ;日期区间是否包含另一个区间或者日期; //intersects();两个日期区间是否存在交集; //intersection() ;返回两个区间的交集,如果无交集返回一个无效区间; //is_adjacent();两个日期区间是否相邻; date_period dp(date(2010, 1, 1), days(20)); //1-1至1-20 assert(dp.is_after(date(2009, 12, 1))); assert(dp.is_before(date(2010, 2, 1))); assert(dp.contains(date(2010, 1, 10))); date_period dp2(date(2010, 1, 5), days(10)); assert(dp.contains(dp2)); assert(dp.intersects(dp2)); assert(dp.intersection(dp2) == dp2); date_period dp3(date(2010, 1, 21), days(5)); //1-21至1-26 assert(!dp3.intersects(dp2)); assert(dp3.intersection(dp2).is_null()); assert(dp.is_adjacent(dp3)); assert(!dp.intersects(dp3)); } //date_period 提供了两种并集操作 { //merge() 返回两个区间的并集,如果区间无交集或者不相邻则返回无效区 //span() 合并两日期区间及两者间的间隔,相当于广义的merge(). date_period dp1(date(2010, 1, 1), days(20)); date_period dp2(date(2010, 1, 5), days(10)); date_period dp3(date(2010, 2, 1), days(5)); date_period dp4(date(2010, 1, 15), days(10)); assert(dp1.contains(dp2) && dp1.merge(dp2) == dp1); assert(!dp1.intersects(dp3) && dp1.merge(dp3).is_null()); assert(dp1.intersects(dp2) && dp1.merge(dp4).end() == dp4.end()); assert(dp1.span(dp3).end() == dp3.end()); } //date_time库的迭代器 { //主要包括date_iterator,week_iterator,month_iterator,year_iterator,年,周,月,天, //重载++,-- 只提供前置重载操作。 date d(2006, 11, 26); day_iterator d_iter(d); assert(d_iter == d); ++d_iter; //递增1天 assert(d_iter == date(2006, 11, 27)); year_iterator y_iter(*d_iter, 3); //增减步长为3年 assert(y_iter == d + days(1)); ++y_iter; //递增3年 assert(y_iter->year() == 2009); } //is_leap_year()判断年份是否是闰年,end_of_month_day() 给定年份和月份,返回该月的最后一天。 { typedef gregorian_calendar gre_cal; cout << "y2010 is" << (gre_cal::is_leap_year(2010) ? "" : "not") << "a leap year." << endl; assert(gre_cal::end_of_month_day(2010, 2) == 28); } return false; } //实现一个打印月历的功能,指定一个日期,可以得到该月的起始和结束日期。 bool show_date_time() { date d(2008, 11, 20); //实际远行时日期可以从CIN获得 date d_start(d.year(), d.month(), 1); //当月第一天 date d_end = d.end_of_month(); //当月最后一天 //构造日期迭代器;d_iter!=d_end;循环结束条件 for (day_iterator d_iter(d_start); d_iter != d_end; ++d_iter) { cout << *d_iter << " " << d_iter->day_of_week() << endl; } return false; } //下面的程序计算一个人十八岁的生日是星期几,当月有几个星期天,当年有多少天。 bool count_age() { date d(2008, 11, 16); //声明日期对象 date d18years = d + years(18); //加上18年 cout << d18years << " is " << d18years.day_of_week() << endl; int count = 0; //星期天的计数器 for (day_iterator d_iter(date(d18years.year(), d18years.month(), 1)); d_iter != d18years.end_of_month(); ++d_iter) { if (d_iter->day_of_week() == Sunday) // 是星期天则计数增加 { ++count; } } cout << "total " << count << " Sundays." << endl; count = 0; for (month_iterator m_iter(date(d18years.year(), 1, 1)); m_iter < date(d18years.year() + 1, 1, 1); ++m_iter) { count += m_iter->end_of_month().day(); //累加月份的天数 } cout << "total " << count << " days of year." << endl; //计算当年的天数没有必要累加每月的天数,可以简单地只判断该年是否是闰年就可以了。如下所示: typedef gregorian_calendar gre_cal; cout<<(gre_cal::is_leap_year(d18years.year())?365:366); cout << endl; return false; } //信用卡计算示例: class credit_card { public: string bank_name; //银行名 int bill_day_no; //记账日 credit_card(const char* bname, int no): //构造函数 bank_name(bname), bill_day_no(no){} int calc_free_days(date consume_day = day_clock::local_day())const { date bill_day(consume_day.year(), consume_day.month(), bill_day_no); //得到记账日 if (consume_day > bill_day) //消费日是否已经过了记账日 { bill_day += months(1); //如果过了则是下个月的记账日 } return (bill_day - consume_day).days() + 20; //计算免息期 } //为了支持比较操作,还需要为credit_card 增加小于比较操作符重载 friend bool operator<(const credit_card& l, const credit_card& r) { //比较免息期 return l.calc_free_days() < r.calc_free_days(); } }; //时间测试示例 //如果在头文件posix_time.hpp之前定义宏BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG,哪么它可以精确到纳秒级。 bool test_time_duration() { //time_duration也有几个子类,可以度量不同的时间分辨率。分别是: //hours,minutes,seconds,millisec/milliseconds,microsec/microseconds,nanosec/nanoseconds. //操作时间长度 {//创建一个1小时10分钟30秒1毫秒(1000微秒)的时间长度 time_duration td(1, 10, 30, 1000); //2小时01分06.001秒 time_duration tdd(1, 60, 60, 1000 * 1000 * 6 + 1000); } {//time_duration的子类可以更直观地创建时间长度 hours h(1); //1小时 minutes m(1); //10分钟 seconds s(30);//30秒钟 millisec ms(1); //1毫秒 time_duration td = h + m + s + ms; //可以赋值给time_duration time_duration td2 = hours(2) + seconds(10); //可以直接赋值 } {//使用工厂函数duration_from_string(),time_duration可以从一个字符串创建字符串中的时间需要冒号隔开 time_duration td = duration_from_string("1:10:30:001"); } { //可以用hours(),minutes(),seconds() 成员函数访问 //total_seconds(),total_milliseconds(),total_microseconds()分别返回时间长度的总秒,毫,微数。 //fractional_seconds()以long返回微秒数 time_duration td(1, 10, 30, 1000); assert(td.hours() == 1 && td.minutes() == 10 && td.seconds() == 30); assert(td.total_seconds() == 1 * 3600 + 10 * 60 + 30); assert(td.total_milliseconds() == td.total_seconds() * 1000 + 1); assert(td.fractional_seconds() == 1000); } { //time_duration 可以取负值,专门有一个成员函数is_negative() 来判断它的正负号。 //成员函数invert_sign()可以将时间长度改变符号后生成一个新的时间长度。 hours h(-10); assert(h.is_negative()); time_duration h2 = h.invert_sign(); assert(!h2.is_negative() && h2.hours() == 10); } { //time_druation也可以赋值为特殊时间值,包括not_a_date_time、pos_infin 等等,同样也有类似的 //is_xxx()函数用于检测它是否为特殊时间,用法与date、date_duration类似。 time_duration td1(not_a_date_time); assert(td1.is_special() && td1.is_not_a_date_time()); time_duration td2(neg_infin); assert(td2.is_negative() && td2.is_neg_infinity()); } { //time_duation支持完整的四则运算。 time_duration td1 = hours(1); time_duration td2 = hours(2) + minutes(30); assert(td1 < td2); assert((td1 + td2).hours() == 3); assert(td1 * 5 == td2 * 2); assert((td1 / 2).minutes() == td2.minutes()); } { //time_duation转换字符串 time_duration td(1, 10, 30, 1000); cout << to_simple_string(td) << endl; cout << to_iso_string(td) << endl; //输出结果:01:10:30.001000 011030.001000 //另外timer_duration也可以转换到 tm结构to_tm()函数 } //时间点 { { //ptime 是在date_time库处理时间的核心类 //using namespace boost::gregorian; posix_time名字空间不包含gregorian名字空间,因此需要加上对它的引用 ptime p(date(2010, 3, 5), hours(1)); //2010年3月5日凌晨1时 } { //ptime可以从字符串构造,使用工厂函数time_from_string()和from_iso_string()前者使用分隔符分隔日期时间成分, //后者则是连结续的数字,日期与时间用字母T隔开 ptime p1 = time_from_string("2010-3-5 01:00:00"); ptime p2 = from_iso_string("20100305T010000"); } { //date_time库为ptime也提供了时钟类,可以从时钟产生当前时间,有两个类second_clock和microsec_clock分别提供秒级和微秒级的分辨率, //它们的接口是相同的,local_time()获得本地当前时间,universal_time()获得UTC当前时间。 ptime p1 = second_clock::local_time(); //秒精度 ptime p2 = microsec_clock::universal_time(); //微秒精度 cout << p1 << endl << p2; } { //ptime构造为特殊时间值,如无效时间,无限时间,也同样有is_xxx()来检验特殊值。 ptime p1(not_a_date_time); //无效时间 assert(p1.is_not_a_date_time()); ptime p2(pos_infin); //正无限时间 assert(p2.is_special() && p2.is_pos_infinity()); } { //操作时间点对象 //ptime使用date()和time_of_day() 两个成员函数获得时间点的日期和时间长度,然后就可以分别处理。 //2010年3月20日中午 12:30 ptime p(date(2010, 3, 20), hours(12) + minutes(30)); date d = p.date(); time_duration td = p.time_of_day(); assert(d.month() == 3 && d.day() == 20); assert(td.total_seconds() == 12 * 3600 + 30 * 60); //ptime支持比较操作与加减运算,运算规则与日期类似 ptime p1(date(2010, 3, 20), hours(12) + minutes(30)); ptime p2 = p1 + hours(3); //2010年3月20日15:30 assert(p1 < p2); assert(p2 - p1 == hours(3)); p2 += months(1); assert(p2.date().month() == 4); } { //ptime提供了三个自由函数转换为字符串,分别是 //to_simple_string(ptime): 转换为YYYY-MMM-DD HH:MM:SS.FFFFFFFFF格式 //to_iso_string(ptime): 转换为YYYYMMDDTHHMMSS,FFFFFFFFF格式 //to_iso_extended_string(ptime):转换为YYYY-MM-DDTHH:MM:SS,FFFFFFFFF格式 //FFFFFFF是秒的小数部分,如果为0则不显示,T是日期与时间的分融符。 ptime p(date(2010, 2, 14), hours(20)); cout << to_simple_string(p) << endl; cout << to_iso_string(p) << endl; cout << to_iso_extended_string(p) << endl; } { //与tm、time_t等结构的转换 //使用自由函数to_tm(),ptime可以单向转换到tm结构,转换规则是date 和 time_duration的组合 ptime p(date(2010, 2, 14), hours(20)); tm t = to_tm(p); assert(t.tm_year == 110 && t.tm_hour == 20); } { //从time_t和FILETIME结构创建出ptime对象,这种转换也是单向的,不存在逆向的转换。 ptime p = from_time_t(std::time(0)); assert(p.date() == day_clock::local_day()); /* FILETIME ft; ft.dwHighDateTime = 29715317; ft.dwLowDateTime = 3865122988UL; p = from_ftime<ptime>(ft); */ } { //time_period一些用法的代码 ptime p(date(2010, 1, 1), hours(12)); //2010年元旦中午 time_period tp1(p, hours(8)); //一个8小时的区间 time_period tp2(p + hours(8), hours(1)); //1小时的区间 assert(tp1.end() == tp2.begin() && tp1.is_adjacent(tp2)); assert(!tp1.intersects(tp2)); //两个区间相邻但不相交 tp1.shift(hours(1)); //tp1平移1小时 assert(tp1.is_after(p)); //两个区间现在相交 assert(tp1.intersects(tp2)); tp2.expand(hours(10)); //tp2向两端扩展10小时 assert(tp2.contains(p) && tp2.contains(tp1)); } { //时间迭代器,只有一个time_iterator //使用时间迭代器以10分钟为步长打印时间 ptime p(date(2010, 2, 27), hours(10)); for (time_iterator t_iter(p, minutes(10)); t_iter < p + hours(1); ++t_iter) { cout << *t_iter << endl; } } { //date_facet、time_facet格工化对象,定制日期时间。 date d(2010, 3, 6); date_facet* dfacet = new date_facet("%Y年%m月%d日"); cout.imbue(locale(cout.getloc(), dfacet)); cout << d << endl; time_facet *tfacet = new time_facet("%Y年%m月%d日%H点%M分%S%F秒"); cout.imbue(locale(cout.getloc(), tfacet)); cout << ptime(d, hours(21) + minutes(50) + millisec(100)) << endl; } } return false; } int main() { //date_time测试示例 test_date_time(); //显示打印月历 show_date_time(); //计算一个人十八岁的生日是星期几,当月有几个星期天,当年有多少天。 count_age(); //信用卡免息期 credit_card a("A bank",25); //A银行记账日是每月的25号 credit_card b("B bank", 12); //B银行记账日是每月的12号 credit_card tmp = std::max(a, b); cout << "You should use " << tmp.bank_name << ", free days = " << tmp.calc_free_days() << endl; //时间测试示例函数调用 test_time_duration(); system("pause"); return 0; }