您的位置:首页 > 其它

Boost之日期时间处理(date_time库)

2016-06-24 22:04 567 查看

概述

使用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类型,但行为不太相同。
<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>


输出:
dd1 + dd2 = 5

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-01

dp1.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年<
b4be
br />

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.001000

td2: 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:00

2002-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:00

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