您的位置:首页 > 其它

Boost库学习随记二 date_time、time_duration、date_facet、time_facet、timer库示例等:

2014-04-09 17:30 295 查看
//"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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: