C++Boost库学习之Date_time库
目录
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 :: 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;
}