[Boost]boost的时间和日期处理日期的操作和时间的操作

参考 

http://www.cnblogs.com/lidabo/p/3938978.html 

http://www.cnblogs.com/lidabo/p/3938969.html



Boost.DateTime库提供了时间日期相关的计算、格式化、转换、输入输出等等功能,为C++的编程提供了便利。不过它有如下特点:

1. Boost.DateTime 只支持1400年以后的任何Gregorian日历日期。如果你需要计算再早的日期,则需要寻求其他库来支持。

日期和时间是编程过程中常用的操作。在C标准库中,<time.h>提供了time_t类型、和tm结构类型的时间日期相关函数。Windows API也提供了FILETIME类型的相关函数。由于这里是介绍boost,就不比较这几种之间的优劣了,感兴趣的朋友可以深究一下,相信你会根据自己的需要进行选择。那么,下面我将根据不同情形大概介绍一下Boost.DateTime中的主要功能。如果你需要严格的时间精度计算,请参看Boost.DateTime稳定度和精度的讨论

*基本概念:

时间点(Time Point)- 某一个时间,例如上午11点钟。

时间段(Time Duration)- 一段时间,不特指起止时间,例如1小时。

时间窗口(Time Interval、Time Period)- 一段时间,从某个时间点到另一时间点,例如下午2点到3点。

时间系统(Time System)- 特定的时间表示、计算规则的体系。

日历系统(Calendar System)- 以一天为基础的时间系统。Gregorian Calender是一个标准的日历系统。

UTC时间(Coordinated Universal Time),支持闰秒的标准时间系统。类似的有格林威治时间GMT。

DST时间(Daylight Savings Time - 夏令时冬令时)很多国家地区在夏天会调整本地时间。

时区(Time Zone) - 使用特定DST规则和与标准时之间时间偏差规则的地区或国家。

Epoch - 日期系统和时钟系统的起点。不同的时间系统起点不一样,通常UTC起点为1970年1月1号0点。

TAI Time - 高精度的时间系统,使用原子时,这个太深奥了,没有具体研究过。

注:下列关于Boost.DateTime输入输出的操作,请参看另一篇介绍:Boost.DateTime的IO操作。

头文件:

#include <boost/date_time/posix_time/posix_time.hpp>

例1. 日期计算:打印今天日期;今年感恩节(11月的第4个星期四)的日期;如果还没有到今年感恩节,打印今天到感恩节还有多少天。

using namespace boost::gregorian;
typedef nth_day_of_the_week_in_month nth_dow;
date today = day_clock::local_day(); //today
std::cout << "today is: " << today << std::endl;
nth_dow fourth_thur_in_nov(nth_dow::fourth,Thursday,Nov); // 4th thursday in Nov
date thanksgiving = fourth_thur_in_nov.get_date(today.year()); // get the date this year
std::cout << "Thanksgiving day this year is: " << thanksgiving << std::endl;
 
 
if(today < thanksgiving)
{
date_duration dd = thanksgiving - today; //date duration
std::cout << "has " << dd.days() << " days to thanksgiving."<< std::endl;
}

A. 对于date对象

>> 要获取一个date对象,可以通过date的4种构造函数:

1:  date d(2013,Jan,10);//constructor from grep y/m/d
2:  date d1(d);//copy constructor
3:  /*special date values*/
4:  date d2(neg_infin);
5:  date d3(pos_infin);
6:  date d4(not_a_date_time);
7:  date d5(max_date_time);
8:  date d6(min_date_time);
9:  date d7; //default constructor

 >> 也可以通过string字符串获得:

1:      using namespace boost::gregorian;
2:  date d(from_string("2002/1/25"));
3:  date d1(from_string("2002-1-25"));
4:  date d2(from_undelimited_string("20020125"));
5:  

 >> 还可以从时钟获得:

1:      using namespace boost::gregorian;
2:  date d(day_clock::local_day()); //获取本地日期
3:  date d1(day_clock::universal_day());//获取GMT日期
4:  

 >>要访问date对象,或进行一些日期判断,请参考下面代码:

 1:      using namespace boost::gregorian;
 2:  date today = day_clock::local_day();
 3:  std::cout << today.year() << std::endl; //打印年
 4:  std::cout << today.month() << std::endl; //打印月
 5:  std::cout << today.day() << std::endl; //打印日
 6:  std::cout << today.week_number() << std::endl;//今年的第几周
 7:  std::cout << today.day_of_week() << std::endl; //打印星期几
 8:  std::cout << today.day_of_year() << std::endl; //打印一年中的第几天
 9:  std::cout << today.end_of_month() << std::endl; //打印本月的最后一天是,闰月的2月,可以试试
10:  std::cout << today.modjulian_day() << std::endl;
11:  std::cout << today.julian_day() << std::endl;
12:  
13:      if(today.is_infinity())
14:  // today.is_neg_infinity();today.is_pos_infinity();today.is_not_a_date();
15:      // today.is_special();
16:      // today.as_special();
17:  {
18:  std::cout << "True" << std::endl;
19:  }
20:  else
21:  {
22:  std::cout << "False" << std::endl;
23:  }
24:  

>>我们经常还需要将时间转换为string类型,请参考:

1:  using namespace boost::gregorian;
2:  date today = day_clock::local_day();
3:  std::string str1(to_simple_string(today));//YYYY-MMM-DD, 2013-Jan-11
4:  std::string str2(to_iso_string(today));//YYYYMMDD, 20130111
5:  std::string str3(to_iso_extended_string(today));//YYYY-MM-DD, 2013-01-11
6:  std::cout << str1 << std::endl << str2 << std::endl << str3 << std::endl;

>>date对象还能够和tm互相转换: 

1:  using namespace boost::gregorian;
2:  date today = day_clock::local_day();
3:  tm d_tm = to_tm(today); // tm struct, year start from 1900, and Jan is 0, Sunday is 0
4:  std::cout << d_tm.tm_year << std::endl << d_tm.tm_mon << std::endl << d_tm.tm_mday << std::endl;
5:  std::cout << d_tm.tm_wday << std::endl;

 B. 对于date_duration对象

 

 

 

date_duration可以由多种方式构造,操作符+/-可以计算date,date_duration等,具体如下。

 1:      using namespace boost::gregorian;
 2:  date leap_year_date(2004,Jan,31);
 3:  date norm_year_date(2005,Jan,31);
 4:  date_duration dd(3);
 5:  days dd1(10);
 6:  weeks ww(2);
 7:  months mm(1);
 8:  years yy(2);
 9:  
10:  std::cout << (leap_year_date + dd) << std::endl;
11:  std::cout << (leap_year_date + dd1) << std::endl;
12:  std::cout << (leap_year_date + ww) << std::endl;
13:  std::cout << (leap_year_date + mm) << std::endl;
14:  std::cout << (leap_year_date + yy) << std::endl;
15:  
16:  std::cout << (norm_year_date + dd) << std::endl;
17:  std::cout << (norm_year_date + dd1) << std::endl;
18:  std::cout << (norm_year_date + ww) << std::endl;
19:  std::cout << (norm_year_date + mm) << std::endl;
20:  std::cout << (norm_year_date + yy) << std::endl;
21:  

另外,迭代器day_iterator,month_iterator,year_iterator也可以看做定长的date_duration工具,在此不细究。

  C. 对于date_period对象

date_peroid作为一个日期窗口,可用于判断一个日期是否落在这个窗口之间。

用两个date或一个date加上一个days可以创建date_period。改变一个date_period可以用平移shift、也可以用加宽expand,可以合并merge,还可以取一个包含这两个period的最小period,方法为span。不过使用的时候大家得注意约束条件,比如merge的时候,两个period应该相交,不然怎么合呢?

 1:  using namespace boost::gregorian;
 2:  date d_begin(2013,Jan,22);
 3:  date d_end(2013,Apr,1);
 4:  date_period dp(d_begin,d_end);//constructor
 5:  date_period dp1(d_begin,days(20));//constructor 2
 6:  
 7:  std::cout << dp << std::endl;
 8:  dp.shift(days(10));
 9:  std::cout << dp << std::endl;
10:  dp.expand(days(10));
11:  std::cout << dp << std::endl;

到这里,关于boost的date基本方法都有介绍。不过细心的可能发现,11月的第4个星期四问题还没有细说。其实在boost::date_time里面,有多种方法可以得到答案。例子中使用的是nth_day_of_the_week_in_month。大家不妨试试从11月1号开始,用next_weekday找第1个星期四,然后再加3个weeks,之类。

关于时间的处理,和日期非常类似,我也会在续篇中介绍,在此结贴鸟。

<完结>


<开篇>

本篇紧接着boost上篇叙述Boost::DateTime的时间处理。在C++中,常见的时间有time_t, FILETIME和tm,而boost中用ptime。

构造ptime

1.ptime的构造函数有四种:

1:      using namespace boost::posix_time;
2:      using namespace boost::gregorian;
3:  ptime pt(date(2013,Jan,24),time_duration(1,2,3)); //由date和time_duration构造
4:  ptime pt1(date(2013,Jan,24),hours()+nanosec(5));//改变形式的time_duration也能使用
5:  ptime pt2(p1);//拷贝构造函数
6:  ptime pt3(neg_infin);//特殊值构造
7:  ptime p;//默认构造函数,这里p等于not_a_date_time

2.用string构造ptime:

1:      std::string ts1("2013-01-30 23:32:22.000");//固定格式,小数点后支持6位
2:  ptime pt1(time_from_string(ts1));
3:  std::string ts2("20130130T233222");//没有分隔符的date和time
4:  ptime pt2(from_iso_string(ts2));
5:  

3.通过时钟构造ptime:

1:      ptime ct1(second_clock::local_time());
2:  ptime ct2(second_clock::universal_time());
3:  ptime ct3(microsec_clock::local_time());
4:  ptime ct4(microsec_clock::universal_time());
5:  

4.time_t和FILETIME构造ptime:

1:      ptime t = from_time_t(tt); // 其中tt为time_t
2:  ptime t1 = from_ftime<ptime>(ft); //其中ft为FILETIME

ptime访问日期时间

1:      using namespace boost::posix_time;
2:      using namespace boost::gregorian;
3:  ptime now(second_clock::local_time());
4:  std::cout << "today is: " << now.date() << std::endl;
5:  std::cout << "time is: " << now.time_of_day() << std::endl;
6:  

ptime转换为string

1:      std::string now_str(to_simple_string(now));
2:  std::string now_iso_str(to_iso_string(now));
3:  std::string now_iso_ext_str(to_iso_extended_string(now));
4:  std::cout << now_str << std::endl;
5:  std::cout << now_iso_str << std::endl;
6:  std::cout << now_iso_ext_str << std::endl;

ptime与tm,time_t,FILETIME互转

1.tm

 1:     using namespace boost::posix_time;
 2:     using namespace boost::gregorian;
 3:     tm pt_tm;
 4:     pt_tm.tm_year = 113;
 5:     pt_tm.tm_mon = 11;
 6:     pt_tm.tm_mday = 25;
 7:     pt_tm.tm_hour = 2;
 8:     pt_tm.tm_min = 23;
 9:     pt_tm.tm_sec = 40;
10:  
11:     ptime pt = data_from_tm(pt_tm);
12:     std::cout << pt << std::endl;
13:  
14:     pt = pt + hours(2);
15:     tm pt_tm1 = to_tm(pt);

2. time_t

 1:      using namespace boost::posix_time;
 2:      using namespace boost::gregorian;
 3:  
 4:  time_t now = time(NULL);
 5:  std::cout << "time_t : " << now << std::endl;
 6:  ptime now_pt = from_time_t(now);
 7:  std::cout << "ptime from time_t : " << now_pt.time_of_day() << std::endl;
 8:  tm* now_tm = gmtime(&now);
 9:  std::cout << "tm struct: hour : " << now_tm->tm_hour << std::endl;
10:  

3.FILETIME

1:      FILETIME ft;
2:  ft.dwHighDateTime = 29715317;
3:  ft.dwLowDateTime = 3865122988UL
4:      ptime pt = from_ftime<ptime>(ft);
5:  // pt ===> 2005-Jun-07 15:30:57.03958200
6:  

time_duration和time_period

 1:      using namespace boost::posix_time;
 2:      using namespace boost::gregorian;
 3:  
 4:  time_duration td(100,200,3,9);
 5:  std::cout << td << std::endl;
 6:  date d(2013,Feb,5);
 7:  ptime pt(d,minutes(10));
 8:  ptime pt1(d,hours(10));
 9:  time_period tp(pt,pt1);
10:  std::cout << tp << std::endl;
11:  

对于这两者的区别,一个是时间间隔,一个是时间起止的一个窗口。time_duration用于ptime的时间偏移计算为主。而time_period可以计算一个ptime时间点是否在这个时间区间内(参考contains函数)。time_period在创建之后可以扩展,可以平移,函数分别为expand和shift。请大家自己细究。

下一篇将介绍关于boost.datetime的格式化输入输出。

<完结>


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值