深入浅出学习boost的date_time库(一 )
来源:互联网 发布:淘宝虚标电池 编辑:程序博客网 时间:2024/05/02 00:09
一、概述
有过编程经验的人都知道,在我们的工作中基本上都会涉及到字符串的处理,各们编程语言,对字符串的处理的函数也尤其多。除此以外,我们项目的开发中很多地方也会涉及到对时间的处理,比如打日志的时候以日期做为后缀名。
日期和时间在程序中就像字符串处理一样经常出现。而我们今天要讲的就boost的一个与时间处理相关的库date_time
库。date_time
库需要编译才能使用,在jamfile中指定lib语句是lib boost_date_time
。date_time
库中包含两个组件,处理日期的组件gregorian(boost/date_time/gregorian/gregorian.hpp)
和处理时间的组件posix_time(boost/date_time/posix_time/posix_time.hpp)
。
二、date_timer库详解
1、处理日期
date_time库的日期是基于格里高利历,支持从1400-01-01到9999-12-31之间的日期,如果要使用,需包含头文件gregorian.hpp。
#include <boost/date_time/gregorian/gregorian.hpp>using namespace boost::gregorian
下面是gregorian.hpp中的代码
#ifndef GREGORIAN_HPP__#define GREGORIAN_HPP__#include "boost/date_time/compiler_config.hpp"#include "boost/date_time/gregorian/gregorian_types.hpp"#include "boost/date_time/gregorian/conversion.hpp"#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)#include "boost/date_time/gregorian/formatters_limited.hpp"#else#include "boost/date_time/gregorian/formatters.hpp"#endif#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)#include "boost/date_time/gregorian/greg_facet.hpp"#else#include "boost/date_time/gregorian/gregorian_io.hpp"#endif // USE_DATE_TIME_PRE_1_33_FACET_IO#include "boost/date_time/gregorian/parsers.hpp"#endif
这段代码里面并没有什么,全是文件的引用,这部分没有什么需要深入理解的,而要理解的是里面这些代码文件都是干什么的。关于这些文件是干什么的我们稍后再讨论。
下面我们先说一下date_time库中处理日期的核心类,日期模板基于年-月-日系统日期类的接口shell来表示 , 如gregorian 或iso系统。 它提供了启用计算和比较的基本操作。这个日期表示方式和C tm结构方式基本上不一样。这种类型的目标是在一个具体的类中提供有效的日期操作(加,减)和存储(最小化代表的空间)。 因此,日期使用内部计数表示特定日期。日历参数定义转换年-月-日和内部的规则计数形式。需要执行重的应用程序重复同一日期的格式化效果会更好,这种效果通过使用年-月-日来表示。 在内部,日期使用日期编号来表示日期。 这是一个比较单调的时间表示方式。这种表示允许快速比较以及简化创建写数字操作。基本上, 内部日数调整得像julian日期。 调整由表示为通过第1天的Epoch日期确定日历。 第0天为负无穷大而1且保留任何实际日期自动大于负无穷大。当日期从日期构建或格式化为输出时, 应用适当创建年,月, 天转换来表示。
#ifndef DATE_TIME_DATE_HPP___#define DATE_TIME_DATE_HPP___#include <boost/operators.hpp>#include <boost/date_time/year_month_day.hpp>#include <boost/date_time/special_defs.hpp>namespace boost {namespace date_time { template<class T, class calendar, class duration_type_> class date : private boost::less_than_comparable<T , boost::equality_comparable<T > > { public: typedef T date_type; typedef calendar calendar_type; typedef typename calendar::date_traits_type traits_type; typedef duration_type_ duration_type; typedef typename calendar::year_type year_type; typedef typename calendar::month_type month_type; typedef typename calendar::day_type day_type; typedef typename calendar::ymd_type ymd_type; typedef typename calendar::date_rep_type date_rep_type; typedef typename calendar::date_int_type date_int_type; typedef typename calendar::day_of_week_type day_of_week_type; date(year_type y, month_type m, day_type d) //构造函数 : days_(calendar::day_number(ymd_type(y, m, d))) {} date(const ymd_type& ymd) //拷贝构造函数 : days_(calendar::day_number(ymd)) {} //让编译器来写复制,分配和析构 year_type year() const { ymd_type ymd = calendar::from_day_number(days_); return ymd.year; } month_type month() const { ymd_type ymd = calendar::from_day_number(days_); return ymd.month; } day_type day() const { ymd_type ymd = calendar::from_day_number(days_); return ymd.day; } day_of_week_type day_of_week() const { ymd_type ymd = calendar::from_day_number(days_); return calendar::day_of_week(ymd); } ymd_type year_month_day() const { return calendar::from_day_number(days_); } bool operator<(const date_type& rhs) const { return days_ < rhs.days_; } bool operator==(const date_type& rhs) const { return days_ == rhs.days_; } // 验证是不是特殊的日期 bool is_special()const { return(is_not_a_date() || is_infinity()); } // 验证是不是非日期 bool is_not_a_date() const { return traits_type::is_not_a_number(days_); } 验证是不是一个无穷大的日期值 bool is_infinity() const { return traits_type::is_inf(days_); } // 验证日期是不是大于所有可能的日期 bool is_pos_infinity() const { return traits_type::is_pos_inf(days_); } // 验证日期是不是小于所有可能的日期 bool is_neg_infinity() const { return traits_type::is_neg_inf(days_); } special_values as_special() const { return traits_type::to_special(days_); } duration_type operator-(const date_type& d) const { if (!this->is_special() && !d.is_special()) { // 持续时间潜在类型可能会比日期潜在类型更宽阔 // 因此我们从许多通常固定的基本时间中计算两种持续时间的差异 typedef typename duration_type::duration_rep_type duration_rep_type; return duration_type(static_cast< duration_rep_type >(days_) - static_cast< duration_rep_type >(d.days_)); } else { // 在这种情况下差异将会有一个特别的值 date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); return duration_type(val.as_special()); } } date_type operator-(const duration_type& dd) const { if(dd.is_special()) { return date_type(date_rep_type(days_) - dd.get_rep()); } return date_type(date_rep_type(days_) - static_cast<date_int_type>(dd.days())); } date_type operator-=(const duration_type& dd) { *this = *this - dd; return date_type(days_); } date_rep_type day_count() const { return days_; } //允许从操作符重载中进入内部 date_type operator+(const duration_type& dd) const { if(dd.is_special()) { return date_type(date_rep_type(days_) + dd.get_rep()); } return date_type(date_rep_type(days_) + static_cast<date_int_type>(dd.days())); } date_type operator+=(const duration_type& dd) { *this = *this + dd; return date_type(days_); } //see reference protected: // 这是允许创建一个新的日期类型的私有构造器,不把它暴露给用户是需要类的使用用户理解date类的内部工作机制 explicit date(date_int_type days) : days_(days) {} explicit date(date_rep_type days) : days_(days.as_number()) {} date_int_type days_; };} }#endif
date也可以从一个字符串产生,这需要使用工厂函数from_string()或者from_undelimited_string(),前者使用分隔符(斜杠或者连字符串)分隔年月日格式的字符串,后者则是无分隔符的纯字符串格式。
date d1 = from_string("2017-3-10");date d1(from_string("2017/3/10"))date d1 = from_undelimited_string(2017310);
day_clock
也是一个工厂类,调用它的成员函数local_day()或者universal_day()
会返回一个当天的日期对象,分别是本地日期和UTC日期。day_clock内部使用了标准C的库函数localtime()和gmtime()函数,因此local_day()也是依赖操作系统的时区设置。
cout << day_clock::local_day() << endl;cout << day_clock::universal() << endl;
2.date对象的转换
to_simple_string(date d)
:转换为YYYY-mmm-DD格式的字符串,其中mmm为3字符的英文月份名;
to_is_string(date d)
: 转换为YYYYMMDD格式的字符串;
to_iso_extended_string(date d)
:转换为YYYY-MM-DD格式的数字字符串,date也支持流输入与输出,默认使用YYYY-MM-DD格式。
to_tm(date):date
对象转换到tm;
date_from_tm(tm datetm):tm
转换到date
3.日期长度
日期长度是以天为单位的时长,是度量时间长度的一个标量。它与日期不同,值可以是任意整数,可正可负。基本的日期长度类如下:
#ifndef DATE_TIME_DATE_DURATION__#define DATE_TIME_DATE_DURATION__#include <boost/operators.hpp>#include <boost/date_time/special_defs.hpp>namespace boost {namespace date_time { template<class duration_rep_traits> class date_duration : private boost::less_than_comparable1< date_duration< duration_rep_traits > , boost::equality_comparable1< date_duration< duration_rep_traits > , boost::addable1< date_duration< duration_rep_traits > , boost::subtractable1< date_duration< duration_rep_traits > , boost::dividable2< date_duration< duration_rep_traits >, int > > > > > { public: typedef typename duration_rep_traits::int_type duration_rep_type; typedef typename duration_rep_traits::impl_type duration_rep; explicit date_duration(duration_rep day_count) : days_(day_count) {} date_duration(special_values sv) : days_(duration_rep::from_special(sv)) {} date_duration(const date_duration<duration_rep_traits>& other) : days_(other.days_) {} duration_rep get_rep()const { return days_; } bool is_special()const { return days_.is_special(); } duration_rep_type days() const { return duration_rep_traits::as_number(days_); } static date_duration unit() { return date_duration<duration_rep_traits>(1); } bool operator==(const date_duration& rhs) const { return days_ == rhs.days_; } bool operator<(const date_duration& rhs) const { return days_ < rhs.days_; } date_duration& operator-=(const date_duration& rhs) { days_ = days_ - rhs.days_; return *this; } date_duration& operator+=(const date_duration& rhs) { days_ = days_ + rhs.days_; return *this; } date_duration operator-() const { return date_duration<duration_rep_traits>(get_rep() * (-1)); } date_duration& operator/=(int divisor) { days_ = days_ / divisor; return *this; } bool is_negative() const { return days_ < 0; } private: duration_rep days_; }; struct duration_traits_long { typedef long int_type; typedef long impl_type; static int_type as_number(impl_type i) { return i; } }; struct duration_traits_adapted { typedef long int_type; typedef boost::date_time::int_adapter<long> impl_type; static int_type as_number(impl_type i) { return i.as_number(); } };} }#endif
date_duration支持全序比较操作(==、 !=、 <、>等)
,也支持完全加减法和递增递减操作,用起来很像一个整数。此外date_duration还支持除法运算,可以除以一个整数,但不能除以另一个date_duration,其他的数学运算如乘法、取余、取模则不支持。
date支持加减运算,两个date对象的加操作时无意义的(date_time库会以编译错误的方式通知我们),date主要是与时长概念配合。
案例:
#include <boost/date_time/gregorian/gregorian.hpp>using namespace boost;int main(){ date d1(2000,1,1), d2(2014,11,18); cout << d2 - d1 << endl; assert(d1+(d2-d1) == d2); d1 += days(10); assert(d1.day() == 11); d1 += months(2); assert(d1.month() == 3 && d1.day() == 11); d1 -= years(10); assert(d2.year() == d1.year() = 4);}
- 深入浅出学习boost的date_time库(一 )
- 《Boost程序完全开发》跟踪学习训练一:Boost::date_time库的使用
- boost库学习之 date_time库
- Boost库使用----date_time类库
- 被boost的date_time库郁闷了一把
- boost.date_time
- date_time boost
- Boost库中date_time库介绍
- Boost之日期时间处理(date_time库)
- Boost库学习随记二 date_time、time_duration、date_facet、time_facet、timer库示例等:
- boost date_time使用
- 编译boost date_time
- boost::date_time之时间处理
- boost的多线程学习一
- boost完全开发指南第2章-处理时间5 (date_time库简单运用)
- Boost库学习笔记(一)
- boost log库学习一
- 修改Boost.date_time代码兼容VC6
- AWE2017,机智云推出“机智玛莉”推动家电行业进入生态智能时代
- 错误 net.sf.json.JSONException: There is a cycle in the hierarchy!
- Oracle 用户解锁
- 使用rowid实现高速分页查询
- 判断两个无环链表是否相交,相交则返回相交首结点
- 深入浅出学习boost的date_time库(一 )
- 面向对象建模
- java linux系统 有关服务器的配置
- Myeclipse的插件mybatis-generator创建的配置文件generatorConfig.xml的配置详细说明
- 如何设计一个小而美的秒杀系统?
- js调用oc代码 和 oc调用js代码
- Spring Boot + Mybatis多数据源和动态数据源配置
- ARM Linux 3.x的设备树(Device Tree)
- Android框架学习之Retrofit(三)retrofit和okhttp的区别