欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++Boost库学习之Date_time库

程序员文章站 2024-01-27 18:21:34
...

目录

1.Date_time库概述
2.date类
  ①类定义
  ②使用例子
3.类date_duration
  ①类定义
  ②使用例子
4.类date_period
  ①类定义
  ②使用例子
5.类date_iterator
  ①类定义
  ②使用例子
6.日期生成器/算法
  ①算法定义
  ②使用例子
7.类gregorian_calendar
  ①算法定义
  ②使用例子

1.Date_time库概述 ^

  Date_time库*有三部分,分别为gregorian,local_time和posix_time,可以在命名空间boost::date_time中找到该库的大部分类型。

  其中格里高利(gregorian)系统,即公历系统,是提供基于公历的日期编程系统,当前支持的日期范围为1400-01-01至9999-12-31。该系统的所有类型都可以在命名空间boost :: gregorian中找到。该库支持两个头文件,如下:

  • 包含所有类类但没有输入/输出:boost / date_time / gregorian / gregorian_types.hpp
  • 包括所有类型和输入/输出:boost / date_time / gregorian / gregorian.hpp
  •   当地时间系统,用于管理本地时间,该系统的所有类型都可以在命名空间boost :: local_time中找到,头文件:boost/date_time/local_time/local_time.hpp。

    2.date类 ^

      boost :: gregorian :: date类是日期编程的主要接口。通常,虽然日期类允许从另一个日期进行赋值,但它一旦构造就是不可变的。创建日期的技术包括使用日期迭代器和 日期算法或生成器从时钟读取 当前日期。

      boost :: gregorian :: date内部存储为32位整数类型。该类专门设计为不包含虚函数。此设计允许使用大量日期进行高效计算和内存使用。

      日期的构造验证了所有输入,因此无法构造“无效”日期。从std :: out_of_range派生的各种异常被抛出以指示日期输入的哪个方面无效。

      ①类定义 ^

    class date : public date_time::date
    {
    public:
        //默认构造函数,无效日期
        date();
        //拷贝构造函数
        explicit date(const date&);
        //移动构造函数
        explicit date(date&& );
        //从年月日中构造日期
        date(year_type, month_type, day_type);
        explicit date(const ymd_type&);
        explicit date(const uint32_t&);
        explicit date(date_rep_type);
    
        //special_values有五个值
        //min_date_time:最小的日期,1400-01-01
        //max_date_time:最大的日期,9999-12-31
        //not_a_date_time:无效的日期
        //pos_infin:正无穷大的日期
        //neg_infin:负无穷大的日期
        explicit date(special_values);
        //注:除了用构造函数初始化一个日期对象,也可以通过其它方法创建一个有效日期对象,具体的看例子
    
        //朱利安日可用来计算两个日期的间隔天数
        //朱利安日(公元前4713年1月1日)至当前日期对象间的天数
        uint32 julian_day() const
        //修改后的朱利安日(1858年11月17日)至当前日期对象间的天数
        uint32_t modjulian_day() const;
        uint32_t day_number() const;
    
        //返回当前日期在一年中的周数
        int week_number() const;
        //返回当前日期在一年中的天数,1-366
        day_of_year_type day_of_year() const
        //返回当前月份中的最后一天的日期
        date end_of_month() const;
    
        //返回year_month_day结构。当需要所有3个部分日期时效率更高。
        greg_year_month_day year_month_day() const;
    
        //操作符重载中可与date_duration对象进行加减运算。
    
        //继承来的成员函数
        //分别用于获取日期中的年,月,日
        greg_year year()const;
        greg_month month()const;
        greg_day day()const;
        //获取星期几
        greg_day_of_week day_of_week()const;
    
        //返回朱利安日至当前日期对象的天数
        uint32_t day_count() const;
        uint32_t day_number() const;
    
        //如果日期为正无穷大,则返回true,否则返回false
        bool is_infinity()const;
        bool is_pos_infinity()const;
        //如果日期为负无穷大,则返回true,否则返回false
        bool is_neg_infinity()const;
        //如果日期为无效日期,则返回true,否则返回false
        bool is_not_a_date()const
        //如果日期为special_values中的一种,则返回true,否则返回false
        bool is_special()const
    }

      ②使用例子 ^

    #include<iostream>
    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        date t(2018,9,9);
        cout << "年:" << t.year() << endl;
        cout << "月:" << t.month() << endl;
        cout << "日:" << t.day() << endl;
        //跟上面三个输出一样
        cout << t.year_month_day().year << endl;
        cout << t.year_month_day().month << endl;
        cout << t.year_month_day().day << endl;
    
        cout << "周:" << t.day_of_week() << endl;
        cout << "本月最后一天的日期:" << t.end_of_month() << endl;
    
        cout << "2018年的第" << t.week_number() << "周" << endl;
        cout << "2018年的第" << t.day_of_year() << "天" << endl;
    
    
        //返回修改后的朱利安日(1858年11月17日)朱利安日可以用来计算两个日期的间隔天数
        cout << t.modjulian_day() << endl;
    
        //Julian Day 朱利安日(公元前4713年1月1日)至今的天数
        cout << t.julian_day() << endl;
        cout << t.day_count() << endl;
        cout << t.day_number() << endl;
    
    
        //从分隔日期字符串中构建一个日期对象,可用- , . / 等分隔符作为日期分隔符
        date t1(from_string("2018-9-10"));
        date t2;
        t2 = from_string("2018/9/11");
        //从iso类型日期字符串中构建一个日期对象
        date t3(from_undelimited_string("20180912"));
        //从时钟中构建一个日期对象,其中local_day()根据计算机的时区设置获取当地日期
        date t4(day_clock::local_day());
        //universal_day()获取UTC日期,UTC:协调世界时,又称世界统一时间,世界标准时间,不属于任意时区,UTC日期+8为中国的当地日期
        date t5(day_clock::universal_day());
    
        //转换为string字符串
        cout << to_simple_string(t) << endl;        //输出:2018-Sep-09
        cout << to_iso_string(t) << endl;           //输出:20180909
        cout << to_iso_extended_string(t) << endl;  //输出:2018-09-09
        cout << to_sql_string(t) << endl;           //输出:2018-09-09
    }

    3.类date_duration ^

      boost :: gregorian ::date_duration类为天数持续时间类型,类似的有weeks,months,years。都可用于date类的加减,不过要注意,持续时间类型的加减运用于月末的时候会出现意料之外的结果,如:

    int main()
    {
        date t(2018, 1, 28);
        months m(1);
        t += m;
        cout << t << endl;    //2018-2-28
        t -= m;
        cout << t << endl;    //2018-1-31
        //使用迭代器可避免这种情况
    }

      ①类定义 ^

    class date_duration : public boost::date_time::date_duration
    {
    public:
        //构造一个天数为l的对象,默认为0
        explicit date_duration(long l=0);
        explicit date_duration(date_duration&);
        date_duration(date_time::special_values);
    
        //获取天数
        long days()const;
        //如果天数小于零,则返回true,否则返回false
        bool is_negative()const;
        //如果天数为正负无穷或者无效值,则返回true,否则返回false
        bool is_special()const;
        //返回最小可能的持续时间类型。返回1
        static date_duration unit()
    }

      ②使用例子 ^

    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        date t(2018, 9, 9);
        date_duration dd(5);
        //返回天数
        cout<<dd.days()<<endl;
        cout<<dd.get_rep() << endl;
        //是否为负
        cout << dd.is_negative() << endl;  
        //是否为正负无穷,无效值
        cout << dd.is_special() << endl;
        //返回最小可能持续的时间
        cout << dd.unit() << endl;
        //date对象与date_duration对象的运算
        t += dd;
        cout << t << endl;    //2018-9-14
    
        //分别为周数,月数,年数,跟date_duration一样的用法
        weeks w(2);
        t += w;
        cout << t << endl;    //2018-9-28
        months m(2);
        t += m;
        cout << t << endl;    //2018-11-28
        years y(1);
        t += y;
        cout << t << endl;    //2019-11-28
    }

    4.类date_period ^

      boost :: gregorian :: date_period类提供了两个日期之间范围的表示。

      ①类定义 ^

    class date_period
    {
        //创建一个范围,开始日期为first,结束日期的后一天为end,如果first大于end,则为无效值
        date_period(date first, date end);
        //创建一个以first开始,范围为len的日期范围
        date_period(date first, date_duration len);
        //返回该日期范围的第一天
        date begin() const;
        //返回该日期范围最后一天的后一天
        date end() const;
        //返回该日期范围的最后一天
        date last() const;
        //返回期范围内的天数
        date_duration length() const;
        //判断是否为无效值
        bool is_null() const;
        bool operator==(const date_period&) const;
        bool operator<(const date_period&) const;
        //首尾日期各加上date_duration对象
        void shift(const date_duration&);
        //将开始日期减去date_duration对象,结束日期加上date_duration对象
        void expand(const date_duration&);
        //如果date或date_period在日期范围内,则返回true,否则返回false
        bool contains(const date& point) const;
        bool contains(const date_period&) const;
        //如果日期重叠,即一个包含另一个,则返回true,否则返回false
        bool intersects(const date_period&) const;
        //判断两个日期是否相邻
        bool is_adjacent(const date_period&) const;
        //判断是否在给定日期之前
        bool is_before(const date&) const;
        //判断是否在给定日期之后
        bool is_after(const date&) const;
        //如果两个日期范围有交集,则返回交集,否则返回一个无效日期
        date_period intersection(const date_period&) const;
        //如果两个日期范围有交集,则返回并集,否则返回一个无效日期
        date_period merge(const date_period&) const;
        //返回一个日期范围,包含给定的两个日期,及它们之间的空隙
        date_period span(const date_period&) const;
    }

      ②使用例子 ^

    #include<iostream>
    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        date t(2018, 9, 10);
        date_period dp(from_string("2018-1-1"),t);
        dp.shift(date_duration(5));  //首尾日期各加上5天
        dp.expand(date_duration(5)); //开始日期减去5天,结束日期加上5天
        cout << "日期范围:" << dp << endl;
        cout << "第一天:" << dp.begin() << endl;
        cout << "最后一天的后一天:" << dp.end() << endl;
        cout << "最后一天:" << dp.last() << endl;
        cout << "日期范围内的天数:" << dp.length() << endl;
        cout << "是否为无效值:" << dp.is_null() << endl;
        cout << "是否在范围内:" << dp.contains(from_string("2018, 9, 1")) << endl;
        cout << "是否重叠:" << dp.intersects(date_period(from_string("2018-6-01"), from_string("2018-9-01"))) << endl;
        cout << "是否相邻:" << dp.is_adjacent(date_period(from_string("2018-9-20"), from_string("2018-10-01"))) << endl;
        cout << "是否在给定日期之后:" << dp.is_after(from_string("2018-10-01")) << endl;
        cout << "是否在给定日期之前" << dp.is_before(from_string("2018-10-01")) << endl;
    
        cout << dp.intersection(date_period(from_string("2018-9-01"), from_string("2018-11-01"))) << endl; //输出:2018-9-01至2018-9-19  交集
        cout << dp.merge(date_period(from_string("2018-9-01"), from_string("2018-12-31"))) << endl;        //输出:2018-1-01至2018-12-30 并集
        cout << dp.span(date_period(from_string("2018-10-1"), from_string("2018-12-31"))) << endl;         //输出:2018-1-01至2018-12-30 
    
    }

    5.类date_iterator ^

      日期迭代器提供了迭代日期的标准机制,日期迭代器是双向迭代器。date_iterator是所有日期迭代器的抽象基类,有day_iterator,week_iterator,month_iterator,year_iterator。

      ①类定义 ^

    class date_iterator
    {
        //没有默认的构造函数,有拷贝构造函数和移动构造函数
        //第二个参数为一次迭代几天,几周,几个月或者几年,默认为1。
        date_iterator(date,int);
    
        //只提供前自增和前自减
        date_iterator& operator++();
        date_iterator& operator--();
    }

      ②使用例子 ^

    #include<iostream>
    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        day_iterator p1(from_string("2018-9-10"));
        week_iterator p2(from_string("2018-9-10"),2);
        month_iterator p3(from_string("2018-9-10"));
        year_iterator p4(from_string("2018-9-10"));
    
        cout << *p1 << endl;     //输出:2018-9-10
        cout << *++p2 << endl;   //输出:2018-9-24
        cout << *++p3 << endl;   //输出:2018-10-10
        cout << *--p4 << endl;   //输出:2017-9-10
    }

    6.日期生成器/算法 ^

      日期算法或生成器是用于生成日期的其他日期或日程表的工具。生成器函数从日期的某些部分开始,例如月和日,并提供另一部分,然后生成具体日期。

      ①算法定义 ^

    //虚基类 不能实例化
    class year_based_generator
    {
    public:
        //获取月份
        greg_month month();
        //获取星期
        greg_weekday day_of_week();
        //获取日期
        date get_date();
    }
    //子类
    //获取给定年份和月份的最后一个星期的日期
    class last_day_of_the_week_in_month;
    //获取给定年份和月份的第一个星期的日期
    class first_day_of_the_week_in_month;
    //获取给定月份的第n个星期的日期
    class nth_day_of_the_week_in_month;
    //获取给定日期之后的第一个星期的日期
    class first_day_of_the_week_after;
    //获取给定日期之前的第一个星期的日期
    class first_day_of_the_week_before;
    //获取给定年,月,日的日期
    class partial_date;
    
    这几个类的构造函数都需要用到月份结构体{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths},星期结构体{Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday}。也可以用数字直接表示
    
    //函数
    //返回给定日期距离下一个星期的天数
    int days_until_weekday(date,greg_weekday);
    //返回给定日期距离上一个星期的天数
    int days_before_weekday(date,greg_weekday);
    //返回给定日期下一个星期的日期
    date next_weekday(date,greg_weekday);
    //返回给定日期上一个星期的日期
    date previous_weekday(date,greg_weekday);

      ②使用例子 ^

    #include<iostream>
    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        int year = 2018;
        std::string _date = "2018-9-10";
        //获取给定年份和月份的最后一个星期的日期
        last_day_of_the_week_in_month m1(Sunday,Sep);
        cout << year << "年," << m1.month() << "月,最后一个" << m1.day_of_week() << "的日期为:" << m1.get_date(greg_year(year)) << endl;
        cout << m1.to_string() << endl;          //输出:M9.5.0     第一个对应月份,第二个对应该月的第几次星期,最后一个不知道
        //获取给定年份和月份的第一个星期的日期
        first_day_of_the_week_in_month m2(Sunday,Sep);
        cout << year << "年," << m2.month() << "月,第一个" << m2.day_of_week() << "的日期为:" << m2.get_date(year) << endl;
        cout << m2.to_string() << endl;          
        //获取给定月份的第n个星期的日期
        nth_day_of_the_week_in_month n(nth_day_of_the_week_in_month::second,Sunday,Sep);
        cout << year << "年," << n.month() << "月,第" << n.nth_week() << "个" << n.day_of_week() << "的日期为:" << n.get_date(year) << endl;
        cout << n.to_string() << endl;          
        //cout << n.nth_week_as_str() << endl;   该函数为nth_week()的字符串版本
    
        //获取给定日期之后的第一个星期的日期
        first_day_of_the_week_after d1(Sunday);
        cout << _date << "之后的第一个" << d1.day_of_week() << "的日期为:" << d1.get_date(from_string(_date)) << endl;
        //获取给定日期之前的第一个星期的日期
        first_day_of_the_week_before d2(Sunday);
        cout << _date << "之前的第一个" << d2.day_of_week() << "的日期为:" << d2.get_date(from_string(_date)) << endl;
    
        //获取给定年,月,日的日期
        partial_date pd(1, Sep);
        cout << year << "年," << pd.month() << "月," << pd.day() << "日的日期为:" << pd.get_date(year) << endl;
    
    
        cout << days_until_weekday(from_string("2018-9-10"), greg_weekday(2)) << endl;
        cout << days_before_weekday(from_string("2018-9-10"), greg_weekday(2)) << endl;
        cout << next_weekday(from_string("2018-9-10"), greg_weekday(2)) << endl;
        cout << previous_weekday(from_string("2018-9-10"), greg_weekday(2)) << endl;
    
    }

    7.类gregorian_calendar ^

      gregorian_calendar类实现了创建格里高利日期系统所需的功能。它将日期的年 - 月 - 日形式转换为日数表示并返回。在大多数情况下,这个类只能通过gregorian :: 访问类成员,不会被用户直接使用。但是,有一些有用的函数可能会被使用,例如end_of_month_day函数。

      ①类定义 ^

    大多数都与date类中一样,详细看例子

      ②使用例子 ^

    #include <boost/date_time/gregorian/gregorian.hpp>
    using namespace boost::gregorian;
    using std::cout;
    using std::endl;
    int main()
    {
        gregorian_calendar::year_type a(2018);
        cout << a.max() << endl;
        cout << a.min() << endl;
        gregorian_calendar::day_type b(5);
        cout << b.max() << endl;
        cout << b.min() << endl;
        cout << b.as_number() << endl;
        gregorian_calendar::day_of_week_type c(1);
        cout << c.max() << endl;
        cout << c.min() << endl;
        gregorian_calendar::month_type d(1);
        cout << d.max() << endl;
        cout << d.min() << endl;
        gregorian_calendar::day_of_year_type f(5);
        cout << f.max() << endl;
        cout << f.min() << endl;
        gregorian_calendar::ymd_type e(2018,9,10);
        cout << "------------------------------------" << endl;
        gregorian_calendar::ymd_type ymd(2018, 9, 10);
        cout<<"返回星期:"<<gregorian_calendar::days_in_week()<<endl;
        cout << "返回朱利安天数:"<<gregorian_calendar::day_number(ymd)<< endl;
        cout << "返回日期的星期:"<<gregorian_calendar::day_of_week(ymd) << endl;
        cout <<"给定年,月,确认改月的最后一天"<< gregorian_calendar::end_of_month_day(2018,9) << endl;
        cout << gregorian_calendar::epoch().year << gregorian_calendar::epoch().month<< gregorian_calendar::epoch().day<< endl;
        cout << gregorian_calendar::from_day_number(2458372).year << endl;   //将日期编号转换为ymd结构。
        cout <<"返回该日期在这一年的第几周:"<<gregorian_calendar::week_number(ymd) << endl;
        cout << "返回修改后的朱利安天数:"<<gregorian_calendar::modjulian_day_number(ymd) <<endl;
        cout << "返回朱利安天数:"<<gregorian_calendar::julian_day_number(ymd) << endl;
        cout << "是否是闰年:"<<gregorian_calendar::is_leap_year(2018) << endl;
    
    }