Boost练习2——时间和日期2

2、处理时间

date_time库提供微秒级别的时间系统,但如果需要,它最高可以达到纳秒级别的精确度。

使用date_time时间功能需要以下头文件,同时与处理日期类似,需要编译date_time库:

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

        using namespace boost::posix_time;

(1)、时间长度(time_duration类)

例子:

 

//1.构造时长:1小时10分钟30秒1毫秒
	time_duration td(1, 10, 30, 1000);

	//构造时长:2小时01分06.001秒
	time_duration td1( 1, 60, 60, 1000*1000*6 +1000);

	//构造时长:1小时10分钟30秒1毫秒
	time_duration td2 = hours(1) + minutes(10) + seconds(30)+millisec(1);

	//使用字符串构造时长
	time_duration td3 = duration_from_string( "1:10:30:001");

//2.成员函数
	//2-1.小时数、分钟数、秒数、微秒数
	assert(td3.hours() == 1 && td3.minutes() == 10 && td3.seconds() == 30 && td3.fractional_seconds() == 1000);
	//2-2.总秒数、总毫秒数、总微秒数
	assert( td3.total_seconds() == 1*3600 + 10*60 + 30);
	assert( td3.total_milliseconds() == td3.total_seconds() * 1000 +1 );
	assert( td3.total_microseconds() == td3.total_milliseconds() * 1000);
	//2-3.判断正负号、生成改变符号时长
	hours h( -10 );
	assert( h.is_negative());

	time_duration h2 = h.invert_sign();
	assert( !h2.is_negative() && h2.hours() == 10);
	//2-4.特殊时间值:
	time_duration td4( not_a_date_time );
	assert( td4.is_special() && td4.is_not_a_date_time());
	time_duration td5( neg_infin );
	assert( td5.is_negative() && td5.is_neg_infinity() );
	//比较操作和四则运算
	time_duration td6 = hours(1);
	time_duration td7 = hours(2) + minutes(30);
	assert(td6 < td7);
	assert( (td6+td7).hours() == 3);
	assert( (td6-td7).is_negative() );
	assert( td6*5 == td7 *2 );
	assert( (td6/2).minutes() == td7.minutes() );

//3.输出
	cout<< td <<endl;//HH:MM:SS.fffffffff
	cout<< to_simple_string( td )<<endl; //HH:MM:SS.fffffffff
	cout<< to_iso_string( td )<<endl;// HHMMSS.fffffffff

//4.to_tm()可以将time_duration转换位tm结构,但不能进行反向转换
<span style="white-space:pre">	</span>tm t = to_tm( td );
<span style="white-space:pre">	</span>assert( t.tm_hour == 1 && t.tm_min == 10 &&t.tm_sec == 30);

输出:

 


 

(2)、时间长度的精度

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

定义BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG时,time_duration的时间分辨率将精确到纳秒,构造函数中秒以下的度量单位也会是纳秒。

如果定义宏BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG,

        time_duration td(1, 10, 30, 1000);//最后的数字1000表示1000纳秒。

        fractional_seconds():返回秒的小数部分(有上述宏时单位是纳秒,没有时是微秒);

静态成员:unit()返回一个time_duration对象,它是time_duration计量的最小单位(有上述宏时单位是纳秒,没有时是微秒);

        resolution():返回时间长度分辨率(枚举);

num_fractional_digits()返回秒的小数部分位数(微秒6位,纳秒9位);

tick_per_second()是c中的宏CLOCK_PER_SEC的强化,返回每秒内的时钟数,可以用来编写时间精度无关的代码:

time_duration::tick_type my_millisec = time_duration::ticks_per_second()/1000;//自定义毫秒单位

time_duration td( 1, 10, 30, 10*my_millisec);//1时10分30秒10毫秒

(3)、时间点(ptime)

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

例子:

 

//1.构造时间点
	ptime p( date(2015,1,2), hours(0) );//
	ptime p1 = time_from_string("2015-1-2 14:41:00");//
	ptime p2 = from_iso_string("20150102T144100");
	ptime p3 = second_clock::local_time();//秒精度
	ptime p4 = microsec_clock::universal_time();//微秒精度
	ptime p5( not_a_date_time );//无效时间
	ptime p6( pos_infin );//正无限时间

	//2.操作//获得date和time_duration后分别操作
	date d = p1.date();
	time_duration td = p1.time_of_day();
	ptime p7( date(2015, 1,2), hours(12)+minutes(30) );
	ptime p8 = p7+hours(3);
	assert( p7 < p8);
	assert( p8 - p7 == hours(3) );
	p8 += months( 2);
	assert( p8.date().month() == 3 );

	//3.输出,(转换位字符串)
	ptime p9( date(2015,1,2), hours(20) );
	cout<< to_simple_string(p9) <<endl;//YYYY-mmm-DD HH:MM:SS.fffffffff
	cout<< to_iso_string(p9) <<endl;//YYYYMMDDTHHMMSS.fffffffff
	cout<< to_iso_extended_string(p9) <<endl;//YYYY-MM-DDTHH:MM:SS.fffffffff

	//4.与tm、time_t等结构的转换
	ptime p10( date(2015,1,2), hours(20) );
	tm t = to_tm( p );//转换位tm结构

	ptime p11 = from_time_t( std::time(0) );//time_t转换为ptime
	FILETIME ft;//程序要包含头文件<Windows.h>
	ft.dwHighDateTime = 29715317;
	ft.dwLowDateTime = 3865122988UL;
	p11 = from_ftime<ptime>(ft);//FILETIME转换为ptiem

结果:

 


 

 (3)、时间区间(time_period)

time_period使用pime作为区间两个端点,左闭右开区间,用法与date_period基本相同。

(4)、时间迭代器(time_iterator)

       用法与date_iterator基本相同。

3、高精度计时器的实现

basic_ptimer.h如下:

 

//basic_ptimer.h
#ifndef _BASIC_PTIMER_H
#define _BASIC_PTIMER_H
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;

template<typename Clock = microsec_clock>//缺省使用microsec_clock
class basic_ptimer
{
public:
	basic_ptimer()//构造函数,初始化起始时间
	{
		restart();
	}

	void restart()//重新开始计时
	{
		_start_time = Clock::local_time();
	}

	void elapsed() const//度量流逝的时间
	{
		cout<< Clock::local_time() - _start_time;
	}

	~basic_ptimer()//析构函数自动输出时间
	{
		elapsed();
	}
private:
	ptime _start_time;//私有变量,保存计时开始时间
};

typedef basic_ptimer<microsec_clock> ptimer;
typedef basic_ptimer<second_clock> sptimer;

#endif

用法与progress_timer一样。

 

 

4、date_time库其他

(1)、几个控制date_time库行为的宏

BOOST_DATE_TIME_SOURCE 、BOOST_DATE_TIME_NOL_LIB:指定date_time库的编译设置,定义这些宏,编译器不使用自动链接库功能,而是使用嵌入源码的方式。

DATE_TIME_NO_DEFAULT_CONSTRUCTOR,禁止编译器创造出date和ptime的缺省构造函数,强制它们在构造时必须有一个有效的值,可以避免某些疏忽而导致的错误。

BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES,启用week、months、years等日期区间便捷类型。不想使用它们,可以undef这个宏。

BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG,启用date_time库更高的时间精度,由微秒变为纳秒。

 

(2)、格式化时间

使用date_time库提供的专门格式化对象date_facet、time_facet等来搭配IO流,定制日期时间的表现形式。

 

//格式化时间
	date d( 2010, 3, 6);
	date_facet* dfacet = new date_facet( "%Y年%m月%d日");
	cout.imbue( locale(cout.getloc(), dfacet) );
	cout<< d <<endl;

	time_facet *tfacet = new time_facet( "%Y年%m月%d日%H点%M分%S%F秒");
	cout.imbue( locale(cout.getloc() , tfacet ));
	cout<< ptime( d, hours(21)+minutes(50)+millisec(100))<<endl;


结果:

 

(3)、本地时间

本地时间位于名字空间:boost::local_time,需要包含头文件<boost/date_time/local_time/local_time.hpp>

        time_zone_base:表示时区的抽象类;

local_date_time:含有时区信息的时间对象,由date+time_duration+时区构造;

        date_time库附带了一个小型CSV格式的文本数据库date_time_zonespec.csv,位于libs/date_time/data/下,可以自由使用,这个数据库包含了世界上几乎所有国家和地区的时区信息,tz_database类专门管理这个数据库。

时区编程例子:

 

//1.创建时区数据库对象
	tz_database tz_db;

	//2.打开数据库
	{
		ptimer t;
		
		//假定文本数据库位于当前目录下
		tz_db.load_from_file("date_time_zonespec.csv");//G:\\Boost_Test\\time_duration\\//
	}
	/*if(tz_db.region_list().size() == 0)
	{
		return ;
	}*/
	cout<<endl;

	//3.使用字符串Asia/Shanghai获得上海时区,即北京时间
	time_zone_ptr shz = tz_db.time_zone_from_region( "Asia/Shanghai");

	//4.使用字符串America/New_York获得纽约时区
	time_zone_ptr nyz = tz_db.time_zone_from_region( "America/New_York");

	cout<<"上海时区无夏令时:"<< shz->has_dst() <<endl;
	cout<<"上海时区名称:"<< shz->std_zone_name() <<endl;

	//5.定义含有时区信息的本地时间对象
	local_date_time dt_bj( date(2008,1,7), //北京时间2008.1.7
		    hours(12), //中午12点
			shz, //上海时区
			false );//没有夏令时
	cout<< "上海时间:"<< dt_bj <<endl;

	//6.将北京时间转换为纽约时间
	local_date_time dt_ny = dt_bj.local_time_in( nyz);//
	cout<< "纽约时间:"<< dt_ny<<endl;

 

 

 

发现的问题:

Boost库提供的数据库:date_time_zonespec.csv文件包含三百多个时区/城市信息,然而在使用tz_database类读取时,发现该类只能读取前一百个,如果我要查找的时区/城市位于100行之后,就会查寻失败。

解决方法:

复制一份数据库文件到项目路径,使用写字板或者Notepad++打开数据库,删除其中一些不需要的信息(整行),使自己需要的信息排在前100行之内。

结果:

(4)、序列化

使用boost.serialization库的能力可以将date_time的数据序列化,把日期时间数据存入某个文件,之后再任意的时刻读取恢复,如同流操作一样简单方便。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值