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

概述

使用date_time库需要在编译时加上"-lboost_date_time",而且需要包含以下头文件:
处理日期的组件:#include
处理时间的组件:#include

date类

date是date_time库处理日期的核心类,使用一个32位的整数作为内部存储,以天为单位表示时间点概念。date也全面支持比较操作和输入输入出,我们可以完全把它当成一个像int、string那样的基本类型来使用。
#include 
#include 

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

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;
}

输出:
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 
#include 

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 
#include 

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 
#include 
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 
#include 
#include 
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 
#include 
#include 
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 
#include 
#include 
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


你可能感兴趣的:(C++)