boost-gregorian库
- date类
- date_duration类 = days类
- year month day 类
- generators中包含了类
- 年月日迭代器。注意:month_iterator解决月陷阱
- date_period类
- gregorian_calendar类包含了很多静态function函数,简便判断
#include <boost/date_time/gregorian/gregorian.hpp>
https://www.boost.org/doc/libs/1_49_0/doc/html/date_time/gregorian.html
支持范围:1400-Jan-01 to 9999-Dec-31
namespace : boost::gregorian
头文件:boost/date_time/gregorian/gregorian_types.hpp
,该头文件包含了没有输入/输出依赖性的库的所有类,
boost/date_time/gregorian/gregorian.hpp
该头文件包含了所有types以及所有的输入输出代码。
boost::gregorian::date
是主要的时间类型。
date类
内部以32位整数类型存储。
不包含任何虚函数
构造date时都会进行验证,输入的日期是否正确。
会报出派生于std::out_of_range
的许多异常。
not-a-date-time
可以被用来作为invalid
或null
构造函数
date(greg_year,greg_month,greg_day); //date d(2002,Jan,10); throw bad_year,bad_day_of_month,bad_day_month
date(date d); // 拷贝构造函数 , date d1(d);
date(spcial_values sv); // 专门用于 infinities , not_a_date_time , max_date_time and min_date_time
// date d1(neg_infin);
// date d2(pos_infin);
// date d3(not_a_date_time);
// date d4(max_date_time);
// date d5(min_date_time);
date(); //默认构造函数 等价于由not_a_date_time初始化。
// 注意:该构造函数可以通过 #define DATE_TIME_NO_DEFAULT_CONSTRUCTOR 。 禁用。
// (see compiler_config.hpp)
通过string的构造函数
date from_string(std::string)// 从定界日期开始
// date d = boost::gregorian::from_string("2002-1-25");
// date d = boost::gregorian::from_string("2020/1/25");
date from_undelimited_string(std::string) // iso_type date string example:20020125
// date d = boost::gregorian::from_undelimited_string("20020125");
通过Clock的构造函数
day_clock::local_day() // 根据计算机的时区设置得到本地日期
// date d = day_clock::local_day();
day_clock::universal_day() // Get the UTC day
// date d = day_clock::universal_day();
访问器
greg_year year() const; // Get the year part of date
// date d(2002,Jan,10); d.year(); RETN 2002
greg_month month() const;
greg_day day() const;
greg_ymd year_month_day() const;
// date::ymd_type ymd = d.year_month_day();
// ymd.year RETN 2002
// ymd.month RETN 1
// ymd.day RETN 10
greg_day_of_week day_of_week() const; // Get the day of the week(Sunday,Monday,etc.)
// date d(2002,Jan,10); d.day_of_week(); RETN Thursday
greg_day_of_year day_of_year() const; // Get the day of year. Number from 1 to 366
// date d(2002,Jan,10); d.day_of_year(); RETN 10
date end_of_month() const // RETN a date object set to the last day of the calling objects current month
// date d(2002,Jan,10); d.end_of_month(); RETN 2002-JAN-31
bool is_infinity() const; // RETN true if date either positive or negative infinity
// date d(pos_infin); d.is_infinity(); RETN True
bool is_neg_infinity() const;
bool is_pos_infinity() const;
bool is_not_a_date() const;
bool is_special() const; // RETN true if value is not a date
special_value as_special() const; // RETUN special_value(仍然代表原含义),如果不是返回 not_special
long modjulian_day() const; // RETN 日期的修正过的 modified Julian day
long julian_day() const ; // RETN julian day
int week_number() const ; // RETN ISO 8601 week number of date
转换函数 To String
std::string to_simple_string(date d); // To YYYY-mmm-DD "2020-Jan-10"
std::string to_iso_string(date d); //To YYYYMMDD "20200110"
std::string to_iso_extended_string(date d); // To YYYY-MM-DD "2020-01-10"
运算符
operator<< ; // 流输出运算符
// cout << d << endl;
operator>> ; //流输入运算符
// stringstream ss("2020-Jan-01");
// ss >> d;
支持==
,!=
,>
,<
,>=
,<=
date operator+(date_duration) const; // RETN a date adding a day offset
// date d(2002,Jan,1);
// date_duration dd(1);
// date d2 = d + dd ;
date operator-(date_duration) const; // RETN a date by substracting a day offset
// date d(2002,Jan,1);
// date_duration dd(1);
// date d2 = d - dd;
date_duration operator-(date) const; // RETN a date_duration by subtracting two dates
// date d1(2002,Jan,1);
// date d2(2002,Jan,2);
// date_duration dd = d2 - d1;
Struct tm Functions
tm与date之间的相互转化。
tm to_tm(date); // from date to tm ; Note: tm_hour tm_min are set to zero tm_isdst is set to -1
//date d(2005,Jan,1);
//tm d_tm = to_tm(d);
// tm_year = 105;
// tm_mon = 0;
// tm_mday = 1;
// tm_wday = 6; (Saturday)
// tm_yday = 0;
// tm_hour = 0;
// tm_min = 0;
// tm_sec = 0;
// tm_isdst = -1;
date date_from_tm(tm datetm); // from tm to date ; Note tm_wday,tm_yeda,tm_hour,tm_min,tm_sec,tm_isdst are ignored
// tm d_tm;
// d_tm.tm_year = 105;
// d_tm.tm_mon = 0;
// d_tm.tm_mday = 1 ;
// date d = date_from_tm(d_tm); //d = 2005-Jan-01
Date Duration(aka Days)
days
等价于date_duration
构造函数
date_duration(long); // create a duration count
// date_duration dd(3);
days(special_value sv); // 特殊值的构造函数
// days dd1(neg_infin);
// days dd2(pos_infin);
// days dd3(not_a_date_time);
// days dd4(max_date_time);
// days dd5(min_date_time);
访问器
long days() const; // Get the day count
// date_duration dd(3); dd.days(); RETN 3
bool is_negative() const;
static date_duration unit(); // RETN smallest possible unit of duraton type
// date_duration::unit(); //等价于 date_duration(1);
bool is_special() const;
运算符
支持<<
,>>
,==
,!=
,<
,>
,>=
,<=
date_duration operator+(date_duration) const; // add date durations
// date_duration dd = date_duration(1)+date_duration(2);
date_duration operator-(date_duration) const;
额外的 Duration Types
days的跨度的逻辑表示
months(int num_of_months); // 时间可变 如果当前表示的是最后一天,加一个月 可能是 28 29 30 31不确定
// months single(1);
// date(2005,Jan,1) + single => 2005-Feb-01
// date(2005,Feb,1) + single => 2005-Mar-01
// date(2005,Feb,25) + single => 2005-Mar-31
years(int num_of_years); // 月末同样 日子可能变化
// years single(1);
// date(2003,Feb,28)+single // 2004-Feb-29
// date(2004,Feb,29)+single // 2005-Feb-28
weeks(int num_of_weeks); // n * 7天
// weeks single(1);
// date(2005,Jan,1) + single ; // 2005-Jan-08
Months操作的可逆性 思考
如果是 29 30 这连个日子 加一个月 可能会出现一些问题。为了避免 可以使用month_iterator
// using months duration type
date d(2005, Nov, 29);
d += months(1); // "2005-Dec-29"
d += months(1); // "2006-Jan-29"
d += months(1); // "2006-Feb-28" --> snap-to-end-of-month behavior kicks in
d += months(1); // "2006-Mar-31" --> unexpected result
d -= months(4); // "2005-Nov-30" --> unexpected result, not where we started
// using month_iterator
month_iterator itr(date(2005, Dec, 30));
++itr; // "2006-Jan-30" --> ok
++itr; // "2006-Feb-28" --> snap-to DOES NOT kick in
++itr; // "2006-Mar-30" --> ok
--itr; // "2006-Feb-28" --> ok
--itr; // "2006-Jan-30" --> ok
--itr; // "2005-Dec-30" --> ok, back where we started
To remove these types simply undefine BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES.
Date Period
直接表示两个date之间的ranges。
零长度的Period认为是invalid。
last
指向总比begin
少一个unit
支持一部分为无限制,表示直到通知
构造函数
date_period(date,date); // [begin,end) if end <= begin invalid
// date_period dp(date(2002,Jan,10),date(2002,Jan,12));
date_period(date,days); // [begin,begin+days) if days <= zero invalid
// date_period dp(date(2002,Jan,10),days(2));
date_period(date_period); //拷贝构造函数
Mutators
date_period shift(days); // begin and end 同时增加 days
date_period expand(days); // begin and end 同时减去 days
访问器
date begin(); // RETN first day of period
date last(); // RETN last date in the period
//date_period dp(date(2002,Jan,1),
// date(2002,Jan,10));
//dp.last() --> 2002-Jan-09
date end();
days length(); // RETN 包含日子数
bool is_null(); // 判断是否是valid
bool contains(date); // True if date is within the period. Zero length periods cannot contain any points
bool contains(date_period); // True if date period is within the period
bool intersects(date_period); // True if periods overlap
//date_period dp1(date(2002,Jan,1),
// date(2002,Jan,10));
//date_period dp2(date(2002,Jan,2),
// date(2002,Jan,3));
//dp2.intersects(dp1) --> true
date_period intersection(date_period); // Calculate the intersection of 2 periods. Null if no intersection.
/* date_period dp1(date(2002,Jan,1),
date(2002,Jan,10));
date_period dp2(date(2002,Jan,2),
date(2002,Jan,3));
dp2.intersection(dp1) --> dp2 */
date_period is_adjacent(date_period); //Check if two periods are adjacent, but not overlapping.
/* date_period dp1(date(2002,Jan,1),
date(2002,Jan,3));
date_period dp2(date(2002,Jan,3),
date(2002,Jan,10));
dp2.is_adjacent(dp1) --> true */
date_period is_after(date); // Determine the period is after a given date.
/* date_period dp1(date(2002,Jan,10),
date(2002,Jan,30));
date d(2002,Jan,3);
dp1.is_after(d) --> true */
date_period is_before(date); // Determine the period is before a given date.
/* date_period dp1(date(2002,Jan,1),
date(2002,Jan,3));
date d(2002,Jan,10);
dp1.is_before(d) --> true */
date_period merge(date_period); //Returns union of two periods. Null if no intersection.
/* date_period dp1(date(2002,Jan,1),
date(2002,Jan,10));
date_period dp2(date(2002,Jan,9),
date(2002,Jan,31));
dp2.merge(dp1); //2002-Jan-01/2002-Jan-31 */
date_period span(date_period); //Combines two periods and any gap between them such that begin = min(p1.begin, p2.begin) and end = max(p1.end , p2.end)
/* date_period dp1(date(2002,Jan,1),
date(2002,Jan,5));
date_period dp2(date(2002,Jan,9),
date(2002,Jan,31));
dp2.span(dp1); // 2002-Jan-01/2002-Jan-31 */
转换函数 To String
std::string to_simple_string(date_period dp);
// To [YYYY-mmm-DD/YYYY-mmm-DD] string where mmm is 3 char month name.
// [2002-Jan-01/2002-Jan-31]
运算符
支持<<
,>>
,==
,!=
,<
,>
。 等于号 与比较符互补
其中小于号,当dp1.end() less than dp2.begin() 返回true
其中大于号,当dp1.begin()大于dp2.end()
Date Iterators
所有迭代器,派生于boost::gregorian::date_iterator
综述
date_itrator // 通用基类对所有 day level iterators
day_iterator(date start_date, int day_count=1);// Iterate day_count days at a time. This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided. 只支持前向
/* day_iterator day_itr(date(2005,Jan,1));
++d_itr; // 2005-Jan-02
day_iterator 2day_itr(date(2005,Feb,1),2);
++2d_itr; // 2005-Feb-03 */
week_iterator(date start_date, int week_count=1);// 类似于day
month_iterator(date start_date, int month_count=1); //Iterate month_offset months. There are special rules for handling the end of the month. These are: if start date is last day of the month, always adjust to last day of the month. If date is beyond the end of the month (e.g. Jan 31 + 1 month) adjust back to end of month (for more details and examples of this, see Reversibility of Operations Pitfall. NOTE: the month_iterator is not effected by this pitfall.) This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
/* month_iterator m_itr(date(2005,Jan,1));
++m_itr; // 2005-Feb-01
month_iterator 2m_itr(date(2005,Feb,1),2);
++2m_itr; // 2005-Apr-01 */
year_iterator(date start_date, int year_count=1); // Iterate year_offset years. The year_iterator will always land on the day of the date parameter except when date is Feb 28 in a non-leap year. In this case the iterator will return Feb 29 for leap years (eg: 2003-Feb-28, 2004-Feb-29, 2005-Feb-28). This iterator does not provide postfix increment/decrement operators. Only prefix operators are provided.
Date Generators/Algorithms
举个简单的例子:“The first Sunday in February” ,你只需要输入多少年,会生成一个具体的集合 date
综述
year_based_generator // 统一的 date_generator 基类:partial_date, nth_day_of_the_week_in_month, first_day_of_the_week_in_month, and last_day_of_the_week_in_month.
last_day_of_the_week_in_month(greg_weekday,greg_month); // 计算类似于 last Monday of January
/* last_day_of_the_week_in_month lwdm(Monday,Jan);
date d = lwdm.get_date(2002);
// 2002-Jan-28 */
first_day_of_the_week_in_month(greg_weekday,greg_month); // fisrt Monday of Januray
nth_day_of_the_week_in_month(week_num,greg_weekday,greg_month);
// week_num Publick枚举成员 of nth_day_of_the_week_in_month
// week_num 支持 first to fifth , 其中 fifth等价于last
partial_date(greg_day,greg_month); // 给定月和日,再通过get_date(year)即可获得 date
first_day_of_the_week_after(greg_weekday); // 计算类似于 在2002-Jan-01 之后的 第一个 Sunday
first_day_of_the_week_before(greg_weekday); // 同上之前
函数综述
days days_until_weekday(date,greg_weekday); // 计算从给定周几开始 到给定周几 一共由几天
/* date d(2004,Jun,1); // Tuesday
greg_weekday gw(Friday);
days_until_weekday(d,gw); NOTE: 3 days!! */
days days_before_weekday(date,greg_weekday); // 往前数
date next_weekday(date,greg_weekday); // 产生date对象,表示给定date的下一个weekday日期
date previous_weekday(date,greg_weekday); // 产生date对象,表示给定date的上一个weekday日期
Gregorian Calendar
boost::gregorian::gregorian_calendar
。转换 year-month-day form of date 到 day number 表示 and back
static short day_of_week(ymd_type) //Return the day of the week (0==Sunday, 1==Monday, etc)
//See also gregorian::date day_of_week
static date_int_type day_number(ymd_type) //Convert a ymd_type into a day number. The day number is an absolute number of days since the epoch start.
static short end_of_month_day(year_type, month_type)
// Given a year and month determine the last day of the month.
static ymd_type from_day_number(date_int_type);//Convert a day number to a ymd struct.
static bool is_leap_year(year_type); //Returns true if specified year is a leap year.
// gregorian_calendar::is_leap_year(2000); true