• boost之日期 时间(date_time)


    基础知识:

    如果把时间想象成一个向前和向后都无限延伸的实数轴,那么时间点就是数轴上的一个点,时间段就是两个时间点之间确定的一个区间,时长(时间长度)则是一个有正负号的标量,它是两个时间点之差,不属于数轴。

    时间点、时间段和时长三者之间可以进行运算,例如“时间点+时长=时间点”,“时长+时长=时长”“时间段∩时间段=时间段”、“时间点∈时间段”,等等,但有的运算也是无意义的,如“时间点+时间点”、“时长+时间段”,等等。这些运算都基于生活常识,很容易理解,但在编写时间处理程序时必须注意。

    date_time库支持无限时间和无效时间(NADT,Not Available Date Time)这样特殊的时间概念,类似于数学中极限的含义。时间点和时长都有无限的值,它们的运算规则比较特别,例如“+ oo时间点+时长=+o时间点”,“时间点+ oo时长=+oo时间点”。如果正无限值与负无限值一起运算将有可能是无效时间,如“+ oo时长- oo时长=NADT”。

    data_time

    特殊值含义
    pos_infin表示正无限
    neg_infin表示负无限

    not_a_date_time

    无效时间
    min_date_time可表示的最小日期或时间
    max_date_time可表示的最大日期或时间

    处理日期

    1. template<typename T,typename calendar,typename duration_type_>
    2. class date
    3. {
    4. public:
    5. data(year_type,month_type,day_type);
    6. year_type year() const;
    7. month_type month() const;
    8. day_type day() const;
    9. day_of_week_type day_of_week() const;
    10. ymd_type year_month_day() const;
    11. bool operator<(const day_type&)const;
    12. bool operator==(const day_type&)const;
    13. ......
    14. };

    date是一个轻量级的对象,很小,处理效率很高,可以被拷贝传值。date也全面支持比较操作和流输入输出,因此我们完全可以把它当成一个像int、string那样的基本类型来使用。

    创建日期对象

    date d1;                        //无效

    date d2(2010,1,1);       //数字

    date d3(2000,Jan,1);   //英文

    date d4(d2);                 //拷贝

     date 也允许从一个字符串产生,这需要使用工厂函数from_string ()或from_undelimited_string ()。前者使用分隔符(斜杠或者连字符)分隔年月日格式的字符串,后者则是无分隔符的纯字符串格式。例如:

    date dl = from_string ( "1999-12-31");

    date d2( from_string("2015/1/1"));

    date d3 = from_undelimited_string ( "20011118"" );

     day_clock 是一个天级别的时钟,它也是一个工厂类,调用它的静态成员函数local_day( )或universal_day()会返回一个当天的日期对象,分别是本地日期和 UTC日期。day_clock内部使用了c标准库的1ocaltime ( )和 gmtime ()函数,因此local_day ()的行为依赖于操作系统的时区设置。例如;

    cout<

    cout<

     我们也可以使用特殊时间概念枚举special_values创建一些特殊的日期,在处理如无限期的某些情形下会很有用:

    1. #include
    2. using namespace boost::gregorian;
    3. int main()
    4. {
    5. std::cout<<date(neg_infin)<
    6. std::cout<<date(pos_infin)<
    7. std::cout<<date(not_a_date_time)<
    8. std::cout<<date(max_date_time)<
    9. std::cout<<date(min_date_time)<
    10. }
    11. //
    12. -infinity
    13. +infinity
    14. not-a-date-time
    15. 9999-Dec-31
    16. 1400-Jan-0

    访问日期

    成员函数:

    成员函数year ( ).month ()和day()分别返回日期的年、月、日:

    date(2017,6,1);

    assert(d.year()==2017);

    assert(d.month()==6);

    assert(d.day()==1);

     成员函数year_month_day ()返回一个date : : ymd_type结构,可以一次性地获取年月日数据:

    date::ymd_type ymd=d1.year_month_day();

            assert(ymd.year==2022);

            assert(ymd.month==1);

            assert(ymd.day==10)

    成员函数day _of_week ()返回date 的星期数,0表示星期天。day_of_year()返回date是当年的第几天(最多是366)。end_of_month ( )返回当月的最后一天的date对象:

    date d1(2022,1,10);

            std::cout<

            std::cout<

    //Mon
    //10

    成员函数week number()返回date所在的周是当年的第几周,范围是0至53;

      date d1(2022,1,10);

            std::cout<

    //2

    日期的输出

    三个自由函数:

    date d1(2022,1,10);

            to_simple_string(d1);

            to_iso_string(d1);

            to_iso_extended_string(d1);

    //2022 -Jan-10

    20220110

    2022-01-10

     转化c结构

    to_tm(date) : date转换到tm。tm的时分秒成员(tm_hour/tm_min/tm_sec)均置为0,夏令时标志tm_isdst置为-1(表示未知)。

    date_from_tm(tm datetm) : tm 转换到date。只使用年、月、日三个成员(tm_year/tm_mon/tm_mday),其他成员均被忽略。

    1. #include
    2. #include
    3. #include
    4. using namespace boost::gregorian;
    5. int main()
    6. {
    7. date d1(2022,9,11);
    8. tm t=to_tm(d1);
    9. assert(t.tm_hour==0&&t.tm_min==0);
    10. assert(t.tm_year==122&&t.tm_mday==11);
    11. date d2=date_from_tm(t);
    12. if(d1==d2)
    13. {
    14. std::cout<<"ture"<
    15. }
    16. }
    17. //ture

    日期长度

    日期长度是以天为单位的时长,是度量时间长度的一个标量。它与日期不同,值可以是任意的整数,可正可负。基本的口期长度类是date_duration

    date_duration可以使用构造函数创建一个日期长度,

    成员函数days ()返回时长的天数,

    如果传入特殊时间枚举值则构造出一个特殊时长对象。is_special ()和is_negative ()可以判断date duration对象是否为特殊值、是否是负值。

    unit ( )返回时长的最小单位,即date duration(1)

    date_duration支持全序比较操作(==、!=、<、<=等),也支持完全的加减法和递增递减操作,用起来很像一个整数。此外 date_duration还支持除法运算,可以除以一个整数,但不能除以另一个date_duration,其他的数学运算如乘法、取模、取余则不支持。

    date_time库为date_duration定义了一个常用的typedef: days,这个新名字更好地说明了date duration的含义——它是一个天数的计量。

    用法:

    1. #include
    2. #include
    3. #include
    4. using namespace boost::gregorian;
    5. int main()
    6. {
    7. days dd1(10),dd2(-100),dd3(255);
    8. if(dd1>dd2&&dd1
    9. {
    10. std::cout<<"yes"<
    11. }
    12. if(dd1+dd2==days(-90))
    13. {
    14. std::cout<<"yes"<
    15. }
    16. std::cout<<(dd1+dd3).days()<
    17. }

    为了方便计算时间长度,date_time库还提供了months、years、weeks 等另外三个时长类,分别用来表示月、年和星期,它们的含义与days类似,但行为不太相同。

    months 和 years 全面支持加减乘除运算,使用成员函数number_of_months ()和number_of_years ()可获得表示的月数和年数。weeks是date_duration的子类,除了构造函数以7为单位外其他的行为与days完全相同,可以说是一个days的近义词。

    week w(3);

    assert(w.days()==21);
     

    months m(3);

    years y(2) ;

    months m2=y+m;

    assert(m2.number_of_months()==29);

    assert((y*2).number_of_years()==4);

    日期运算

    date d1(2000,1,1) d1(2017,11,18)

    cout<

    d1+=days(10)

    等。。。。

    日期区间

    date_period来表示日期区间概念

    左闭右开

    常用

    date_period dp(date(2017,1,1),datys(20));

    成员函数:

    成员函数 begin ()和 last ()返回日期区间的两个端点,而end ()返回last()后的第天,与标准容器中的 end ()含义相同,是一个“逾尾的位置”。length ()返回日期区间的度,以天为单位。如果日期区间在构造时使用了左大右小的端点或者日期长度是 0

    date_period可以进行全序比较运算,但比较不是依据日期区间的长度,而是依据区间的端点,即第一个区间的end ()和第二个区间的 begin ( ),判断两个区间在时间轴上的位置大小。如果两个日期区间相交或者包含,那么比较操作无意义。

    日期区间的运算:

    成员函数shift ( )和 expand ()可以变动区间:

    shift()将日期区间平移n天而长度不变,expand ()将日期区间向两端延伸n天,相当于区间长度加2n天。

    成员函数shift ( )和 expand ()可以变动区间: shift()将日期区间平移n天而长度不变,expand ()将日期区间向两端延伸n天,相当于区间长度加2n天。例如:

    date_period还可以使用成员函数判断某个日期是否在区间内,或者计算日期区间的交集:

    is_before/is_after日期区间是否在日期前或后;
    contains()日期区间是否包含另一个区间或者日期;
    intersects()两个日期区间是否存在交集;
    intersections

    返回两个区间的交集,

    is_adjacent()如果无交集返回一个无效区间;两个日期区间是否相邻。

     

    date_period提供啦两种并集操作

    merge ( ) :返回两个区间的并集,如果区间无交集或者不相邻则返回无效区间;

    span () :合并两日期区间及两者间的间隔,相当于广义的merge ().

    日期迭代器

    date_time库为日期处理提供了迭代器的概念,可以用简单的递增或者递减操作符连续访问日期,这些迭代器包括day_iterator.week_iterator.month_iterator和 year_iterator,它们分别以天、周、月和年为单位增减。

    日期迭代器的用法基本类似,都需要在构造时传入一个起始日期和增减步长(可以是一天、两周或者N个月,等等,默认是1个单位),然后就可以用operator++、operator--变化

    日期。迭代器相当于一个date对象的指针,可以用解引用操作符*获得迭代器当前的日期对象,也可以用->直接调用日期对象的成员函数。

    1. #include
    2. #include
    3. #include
    4. using namespace boost::gregorian;
    5. int main()
    6. {
    7. date d1(2022,9,11);
    8. day_iterator d_iter(d1);
    9. assert(d_iter==d1);
    10. ++d_iter;
    11. assert(d_iter==date(2022,9,12));
    12. year_iterator y_iter(*d_iter,10);
    13. assert(y_iter==d1+days(1));
    14. ++y_iter;
    15. std::cout<year()<
    16. }

    处理时间

    1. #include
    2. using namespace boost::posix_time;
    3. #include
    4. int main()
    5. {
    6. //hour minute second millisec
    7. time_duration td(1,10,30,1000);
    8. //自动借位
    9. //2 01 06 1ms
    10. time_duration td1(1,60,60,1000*1000*6+1000);
    11. hours h(1);
    12. minutes m(10);
    13. seconds s(30);
    14. millisec ms(1);
    15. time_duration td2=h+m+s+ms;
    16. std::cout<hours()<
    17. }

    时间精确度:

    date_time 库默认时间的精确度是微秒,纳秒相关的类和函数如nanosec和成员函数nanoseconds ( ) 、total_nanoseconds()都不可用,秒以下的时间度量都使用微秒。

    当定义了宏BOOST_DATE_TIME_POSIx_TIME_STD_CONFIG时,time_duration的一些行为将发生变化,它的时间分辨率将精确到纳秒,构造函数中秒以下的时间度量单位也会变成纳秒。

    1. time_duration td(1,10,30,1000)//1000 ns 1us
    2. cout<

    成员函数:

    成员函数fractional_seconds ()仍然返回秒的小数部分,但单位是纳秒,这也是它的名称不叫milli_seconds ()或者nano_seconds ()的原因:

    静态成员函数unit()返回一个time_duration对象,它是time_duration计量的最小单位,相当于time_duration(0,0,0,1),默认情况下是微秒,如果定义了BOOST_DATE_TIME_POSIX_TIME_STD CONFTG则是纳秒:

    time_duration提供静态成员函数resolution ()和 num_fractional_digits ()来检测当前的精度:

    纳秒

    td.resolution()==date_time::nano

    td.num_frrractional_digits()==9;

    时间点:

     在熟悉了时间长度类time_duration后,理解时间点概念就容易多了,它相当于一个日期再加上一个小于24小时的时间长度。如果时间轴的基本单位是天,那么日期就相当于整数,时间点则是实数,定义了天之间的小数部分。

    ptime是date_time库处理时间的核心类,它使用64位(微秒级别)或者96位(纳秒级别)的整数在内部存储时间数据,依赖于date和time_duration,因此接口很小。

    ptime p1=time_from_string("2017-7-7 01:00:00")

    ptime p(date(2017,7,7),hour(1));

    操作时间点对象

    1. #include
    2. using namespace boost::posix_time;
    3. #include
    4. #include
    5. using namespace boost::gregorian;
    6. int main()
    7. {
    8. time_duration td(11,35,50,1000);
    9. ptime p(date(2022,9,11),td);
    10. std::cout<
    11. date d=p.date();
    12. time_duration td2=p.time_of_day();
    13. std::cout<
    14. p+=minutes(20);
    15. std::cout<
    16. }

    转化c结构

    使用函数to_tm ( ) , ptime可以转换到tm结构,转换规则是date和time_duration的组合,而ptime_from_tm ( )则可以把 tm结构转换成ptime。

    1. #include
    2. using namespace boost::posix_time;
    3. #include
    4. #include
    5. #include
    6. using namespace boost::gregorian;
    7. int main()
    8. {
    9. time_duration td(11,35,50,1000);
    10. ptime p(date(2022,9,11),td);
    11. tm t=to_tm(p);
    12. std::cout<
    13. if(ptime_from_tm(t)==p)
    14. {
    15. std::cout<<"yes"<
    16. }
    17. }
    18. //122

    时间区间

    类似于日期区间

    时间迭代器

    不同于日期迭代器,时间迭代器只有一个time_iterator。它在构造时传入一个起始时间点 ptime对象和一个步长 time_duration对象,然后就同日期迭代器一样使用前置式operator++、operator--来递增或递减时间,解引用操作符返回一个ptime对象。

    1. #include
    2. using namespace boost::posix_time;
    3. #include
    4. #include
    5. #include
    6. using namespace boost::gregorian;
    7. int main()
    8. {
    9. time_duration td(11,35,50,1000);
    10. ptime p(date(2022,9,11),td);
    11. for(time_iterator t_iter(p,minutes(10));
    12. t_iterhours(1);++t_iter)
    13. {
    14. std::cout<<*t_iter<
    15. }
    16. }
    17. //
    18. 2022-Sep-11 11:35:50.001000
    19. 2022-Sep-11 11:45:50.001000
    20. 2022-Sep-11 11:55:50.001000
    21. 2022-Sep-11 12:05:50.001000
    22. 2022-Sep-11 12:15:50.001000
    23. 2022-Sep-11 12:25:50.001000

  • 相关阅读:
    如何实现FPGA的可重复性设计
    爬虫项目实战——爬取B站视频
    SuperMap GIS基础软件安全问题Q&A
    //快速排序的非递归版本
    python 从一道作业题到制作一个图形界面的“诈金花”游戏
    俄罗斯方块c语言
    Cyclopropene-PEG-MAL Maleimide|环丙烯-聚乙二醇-马来酰亚胺
    猿创征文 |【Ant Design Pro】使用ant design pro做为你的开发模板(三) 接入mock数据做持续开发
    Empowering Long-tail Item Recommendation through Cross Decoupling Network (CDN)
    文件目录(文件控制块FCB,目录结构,索引结点)
  • 原文地址:https://blog.csdn.net/qq_62309585/article/details/126802252