C++ Boost库 操作日期与时间

C/C++
326
0
0
2023-02-15

Boost库中默认针对日期与时间的操作库分为,timer,progress_timer,date_time这几类,如下是一些常用的使用方法总结。

timer库

#include <iostream>
#include <vector>
#include <boost\timer.hpp>
#include <boost\progress.hpp>

using namespace std;
using namespace boost;

int main(int argc, char const *argv[])
{
	// timer 时间度量
	timer time;

	cout << "度量最大时间(小时): " << time.elapsed_max() / 3600 << endl;
	cout << "度量最小时间(秒): " << time.elapsed_min() << endl;
	cout << "输出流逝时间: " << time.elapsed() << endl;

	// 输出进度条(foreach循环)
	vector<int> v(100);
	progress_display pd(v.size());
	for (auto &x : v)
	{
		++pd;
		_sleep(10);
	}

	// 输出进度条(迭代器)
	for (auto pos = v.begin(); pos != v.end(); ++pos)
	{
		cout << " " << (pos - v.begin()) << " %" << endl;

		pd.restart(v.size());
		pd += (pos - v.begin() + 1);
	}
	return 0;
}

日期的基本操作 先来简单的,实现一个日期格式的数据

#include <iostream>
#include <boost\date_time\gregorian\gregorian.hpp>

using namespace std;
using namespace boost;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{
	// 普通的date可以直接声明
	date date_a(2021, 01, 01);
	date date_b(2021, Jan, 1);
	cout << "年: " << date_a.year() << " 月: " << date_a.month() << " 日: " << date_a.day() << endl;

	// 通过字符串读入日期
	date date_c = from_string("2019-12-21");
	date date_d = from_undelimited_string("20191221");
	cout << "年: " << date_c.year() << " 月: " << date_c.month() << " 日: " << date_c.day() << endl;

	// 返回当天日期对象
	date date_e = day_clock::local_day();
	date date_f = day_clock::universal_day();
	cout << "当前日期: " << date_e << endl;
	cout << "当前日期: " << day_clock::local_day() << endl;

	// 返回星期数/所在天/周
	date date_g = from_string("2020-12-14");
	if (!date_g.is_not_a_date())
	{
		cout << "该日期是星期几: " << date_g.day_of_week() << endl;
		cout << "该日期是本年第: " << date_g.day_of_year() << " 天" << endl;
		cout << "该日期是本年第: " << date_g.week_number() << " 周" << endl;
	}
	
	return 0;
}

日期格式转换

#include <iostream>
#include <boost\date_time\gregorian\gregorian.hpp>

using namespace std;
using namespace boost;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{
	// 日期格式化输出
	date date_a = from_string("2021-01-25");

	cout << "转为英文格式: " << to_simple_string(date_a) << endl;
	cout << "转为纯数字格式: " << to_iso_string(date_a) << endl;
	cout << "转为通用格式: " << to_iso_extended_string(date_a) << endl;

	// 日期/时间/月份 差值计算
	days day_a(10), day_b(100), day_c(-50);
	cout << "day_b 与 day_a 相差: " << day_b - day_a << " 天" << endl;
	cout << "相加是否大于100: " << ((day_a + day_b).days() > 100) << endl;

	weeks week_a(3), week_b(4);
	cout << "三个星期: " << week_a << " 天" << endl;
	cout << "四个星期等于28: " << (week_b.days() == 28) << endl;

	// 日期混合相加
	years year(2);       // 2年
	months month(5);     // 5个月

	months item = year + month;
	cout << "总计: " << item.number_of_months() << " 个月" << endl;
	cout << "总计: " << (year).number_of_years() << " 年 " << "零 " << month.number_of_months() << " 个月" << endl;
	
	// 日期的运算
	date date_b(2019, 01, 01), date_c(2020, 01, 01);
	cout << "日期相差: " << date_c - date_b << " 天" << endl;

	date_b += months(12);
	cout << "加12个月后: " << date_b << endl;

	date_b -= days(100);
	cout << "减100天后: " << date_b << endl;

	getchar();
	return 0;
}

日期区间运算, 就是指定一个日期范围,对特定范围的操作。

#include <iostream>
#include <boost\date_time\gregorian\gregorian.hpp>

using namespace std;
using namespace boost;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{
	// 指定日期区间
	date_period date_per(date(2020, 1, 1), days(20));
	cout << "当前区间: " << date_per << " 总长度: " << date_per.length().days() << endl;
	cout << "第一天为: " << date_per.begin().day() << " 最后一天: " << date_per.last().day() << endl;

	// 动态变动区间 shift = 区间整体向后延申3天
	date_per.shift(days(3));
	cout << "第一天为: " << date_per.begin().day() << " 最后一天: " << date_per.last().day() << endl;

	// 动态变动区间 expand = 区间分别向前和向后延申2天
	date_per.expand(days(2));
	cout << "第一天为: " << date_per.begin().day() << " 最后一天: " << date_per.last().day() << endl;

	// 区间范围判断: is_before()/is_after() = 日期区间是否在日期前或后
	cout << "是否在2009年之后: " << date_per.is_after(date(2009, 12, 1)) << endl;
	cout << "是否在2009年之前: " << date_per.is_before(date(2009, 12, 1)) << endl;

	// 区间包含判断: contains() 日期区间是否包含另一个区间或日期
	cout << "是否包含2020/01/15: " << date_per.contains(date(2020, 1, 15)) << endl;

	// 区间交集判断: intersects() 判断区间是否存在交集
	date_period date_inter_a(date(2020, 1, 1), days(31));    // 2020-1-1 -> 2020-1-31
	date_period date_inter_b(date(2020, 1, 20), days(30));   // 2020-1-20 -> 2020-2-19
	cout << "两区间是否存在交集: " << date_inter_a.intersects(date_inter_b) << endl;
	
	if (! date_inter_a.intersection(date_inter_b).is_null())
	{
		cout << "输出交集: " << date_inter_a.intersection(date_inter_b) << endl;
	}

	// 区间并集判断: merge()/span() 判断并集与合并
	if (!date_inter_a.intersection(date_inter_b).is_null())
	{
		cout << "合并后的并集: " << date_inter_a.merge(date_inter_b) << endl;
		cout << "合并后的并集: " << date_inter_a.span(date_inter_b) << endl;
	}
	getchar();
	return 0;
}

日期迭代器:

#include <iostream>
#include <boost\date_time\gregorian\gregorian.hpp>

using namespace std;
using namespace boost;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{
	// 日期迭代器(天)
	// 迭代器可分为: day_iterator/month_iterator/year_iterator
	date today(2020, 1, 1);                          // 指定当前日期
	date day_start(today.year(), today.month(), 1);  // 指定当月第一天
	date day_end = today.end_of_month();             // 指定当月最后一天

	for (day_iterator day_iter(day_start); day_iter != day_end; ++day_iter)
	{
		cout << "输出日期: " << *day_iter << " 星期: " << day_iter->day_of_week() << endl;
	}

	// 计算指定 2020/01/01 有几个周末
	int count = 0;
	for (day_iterator day_iter(date(today.year(), 1, 1)); day_iter != today.end_of_month(); ++day_iter)
	{
		// 判断是否为周日
		if (day_iter->day_of_week() == Sunday)
			++count;
	}
	cout << "该月有: " << count << " 个周末." << endl;

	// 计算该年总共多少天
	int count_day = 0;
	for (month_iterator mon_iter(date(today.year(), 1, 1)); mon_iter < date(today.year() + 1, 1, 1); ++mon_iter)
	{
		count_day += mon_iter->end_of_month().day();
	}
	cout << "该年有: " << count_day << " 天" << endl;

	getchar();
	return 0;
}

时间基本操作:

#include <iostream>
#include <boost\date_time\posix_time\posix_time.hpp>

using namespace std;
using namespace boost;
using namespace boost::posix_time;

int main(int argc, char const *argv[])
{
	// 时间的创建与赋值
	time_duration time_a(1, 10, 20, 1000);
	cout << time_a.hours() << " 小时 " << time_a.minutes() << " 分钟 " << time_a.seconds() << " 秒" << endl;
	
	hours h(2); minutes m(10); seconds s(30); millisec ms(1);
	time_duration time_b = h + m + s + ms;
	cout << time_b.hours() << " 小时 " << time_b.minutes() << " 分钟 " << time_b.seconds() << " 秒" << endl;

	time_duration time_c = duration_from_string("2:12:11:001");
	cout << time_c.hours() << " 小时 " << time_c.minutes() << " 分钟 " << time_c.seconds() << " 秒" << endl;

	// 时间的格式化输出
	time_duration time_d(2, 10, 20, 1000);
	cout << "标准格式输出: " << to_simple_string(time_d) << endl;
	cout << "纯数字格式输出: " << to_iso_string(time_d) << endl;

	// 时间的运算
	time_duration time_e(2, 10, 20, 1000);
	cout << "原时间: " << time_e << endl;

	time_e += minutes(10);  // 增加十分钟
	time_e += hours(3);     // 增加三小时
	cout << "当前时间: " << time_e << endl;

	getchar();
	return 0;
}

操作时间点: 时间点是一个日期再加上一个小于24小时的时间长度。

#include <iostream>
#include <boost\date_time\posix_time\posix_time.hpp>

using namespace std;
using namespace boost;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{
	// 创建时间点
	ptime ptime_a(date(2020, 01, 20), hours(2));
	cout << "输出时间点: " << ptime_a << endl;

	ptime ptime_b = time_from_string("2020-1-10 02:12:00");
	cout << "输出时间点: " << ptime_b << endl;

	ptime ptime_c = from_iso_string("20200112T121122");
	cout << "输出时间点: " << ptime_c << endl;

	// 操作时间点(递增递减)
	ptime ptime_d(date(2020, 12, 11), hours(11) + minutes(12) + seconds(50));

	date today = ptime_d.date();
	time_duration time = ptime_d.time_of_day();
	cout << "日期: " << today << " 时间: " << time << endl;

	cout << "递增前: " << ptime_d << endl;
	ptime_d += hours(1);
	ptime_d += days(10);
	cout << "递增后: " << ptime_d << endl;

	// 时间点格式化输出
	ptime ptime_e(date(2020, 1, 1), hours(10));
	cout << "默认时间点格式: " << to_simple_string(ptime_e) << endl;
	cout << "文本格式输出: " << to_iso_string(ptime_e) << endl;
	cout << "标准格式输出: " << to_iso_extended_string(ptime_e) << endl;

	// 日期与时间格式化
	date today(2020, 12, 11);

	date_facet * dfacet = new date_facet("%Y 年 %m 月 %d 日");
	cout.imbue(locale(cout.getloc(), dfacet));
	cout << "格式化中文显示(日期): " << today << endl;

	time_facet * tfacet = new time_facet("%Y 年 %m 月 %d 日 %H 时 %M 分 %S%F 秒");
	cout.imbue(locale(cout.getloc(), tfacet));
	cout << "格式化日期与时间: " << ptime(today, hours(11) + minutes(24) + millisec(59)) << endl;
	
	getchar();
	return 0;
}

时间区间操作: 注意时间迭代器,只有一个time_iterator

#include <iostream>
#include <boost\date_time\posix_time\posix_time.hpp>

using namespace std;
using namespace boost;
using namespace boost::posix_time;
using namespace boost::gregorian;

int main(int argc, char const *argv[])
{

	// 时间日期区间
	ptime ptime_a(date(2020, 1, 1), hours(0) + minutes(20) + seconds(40));
	cout << "先定义日期时间: " << ptime_a << endl;         // 2020-1-1 00:20:40
	time_period time_per_a(ptime_a, hours(12));            // 2020-1-1 12:20:40
	cout << "输出12小时的区间: " << time_per_a << endl;

	// 时间日期交集判断 (time_per_a 与 time_per_b 的交集)
	ptime ptime_b(date(2020, 1, 1), hours(0) + minutes(10) + seconds(60));
	time_period time_per_b(ptime_b, hours(12));            // 2020-1-1 12:10:60
	cout << "是否存在交集: " << time_per_a.intersects(time_per_b) << endl;
	cout << "交集为: " << time_per_a.intersection(time_per_b) << endl;

	// 平移与扩展时间
	time_per_a.shift(hours(1));
	cout << "向后平移一小时: " << time_per_a << endl;

	time_per_a.expand(hours(10));
	cout << "两端扩展10小时: " << time_per_a << endl;

	// 时间迭代器(每次迭代10分钟)
	ptime ptime_c(date(2020, 1, 1), hours(10));
	for (time_iterator t_iter(ptime_c, minutes(10)); t_iter < ptime_c + hours(1); ++t_iter)
	{
		cout << "时间迭代: " << *t_iter << endl;
	}

	getchar();
	return 0;
}

chrono: 时间长度计算,与自定义时间转换。

#include <iostream>
#include <boost/chrono.hpp>
#include <boost/chrono/include.hpp>

#define BOOST_CHRONO_EXITENSIONS

using namespace std;
using namespace boost;

int main(int argc, char const *argv[])
{
	boost::chrono::milliseconds milliseconds(1000);   // 定义1000毫秒
	boost::chrono::seconds seconds(20);               // 定义20秒
	boost::chrono::minutes minutes(30);               // 定义30分钟
	boost::chrono::hours hours(1);                    // 定义1小时

	typedef boost::chrono::duration<long, boost::ratio<30>> half_min;        // 定义半分钟
	typedef boost::chrono::duration<int, boost::ratio<60 * 15>> quater;      // 定义15分钟
	typedef boost::chrono::duration<double, boost::ratio<3600 * 24>> day;    // 定义1天

	cout << "返回时间: " << seconds.count() << endl;
	cout << "单位最小值: " << seconds.min() << " 单位最大值: " << seconds.max() << endl;

	// 时间单位 递增与递减
	seconds *= 2;
	cout << "将秒扩大2倍: " << seconds.count() << endl;

	seconds = seconds + boost::chrono::seconds(100);
	cout << "将秒增加100: " << seconds << endl;

	seconds = seconds - boost::chrono::seconds(40);
	cout << "将秒递减40: " << seconds << endl;

	// 不同时间单位相加 (分钟与秒相加转为秒)
	boost::chrono::seconds temporary;
	temporary = seconds + minutes;
	cout << "100秒加30分钟: " << temporary << endl;

	// 不同时间单位相加 (分钟与秒相加转为分钟)
	typedef boost::chrono::duration<double, boost::ratio<60>> my_minutes;
	my_minutes m(5);
	m += temporary;
	cout << "1900秒加5分钟: " << m << endl;

	// 时间之间类型转换
	boost::chrono::seconds cast_minutes(300);

	boost::chrono::minutes min = boost::chrono::duration_cast<boost::chrono::minutes>(cast_minutes);
	cout << "300秒转为分钟: " << min << endl;

	boost::chrono::seconds cast_seconds(3600 + 30);   // 1小时30秒
	cout << "输出60分钟: " << boost::chrono::floor<boost::chrono::minutes>(cast_seconds) << endl;
	cout << "输出61分钟: " << boost::chrono::ceil<boost::chrono::minutes>(cast_seconds) << endl;
	cout << "输出60分钟: " << boost::chrono::round<boost::chrono::minutes>(cast_seconds) << endl;
	cout << "输出1小时: " << boost::chrono::round<boost::chrono::hours>(cast_seconds) << endl;


	getchar();
	return 0;
}

时钟与时间点:

#include <iostream>
#include <boost/chrono.hpp>
#include <boost/chrono/include.hpp>

#define BOOST_CHRONO_EXITENSIONS

using namespace std;
using namespace boost;

int main(int argc, char const *argv[])
{
	// 时间点的简单转换
	auto pt_a = boost::chrono::system_clock::now();
	cout << "获取时间点: " << pt_a << endl;
	cout << "初始时间点到现在的秒数: " << pt_a.time_since_epoch() << endl;

	auto day = pt_a.time_since_epoch();
	cout << "将秒数转为小时: " << boost::chrono::duration_cast<boost::chrono::hours>(day) << endl;

	// 时间点的计算
	auto pt_b = pt_a + boost::chrono::minutes(10) + boost::chrono::hours(10);
	cout << "将pt_b加10分钟在加10小时: " << pt_b << endl;

	// 获取计算机启动时间
	auto pt_c = boost::chrono::steady_clock::now();
	auto tmp = pt_c.time_since_epoch();
	cout << "计算机启动时间: " << boost::chrono::round<boost::chrono::hours>(tmp) << endl;

	// 时间点转为实际时间
	auto time = boost::chrono::system_clock::to_time_t(pt_a);
	cout << "输出字符串日期: " << std::ctime(&time) << endl;


	getchar();
	return 0;
}

CPU利用率:

#include <iostream>
#include <boost/timer/timer.hpp>

using namespace std;
using namespace boost;

int main(int argc, char const *argv[])
{
	boost::timer::auto_cpu_timer timer;

	!timer.is_stopped();    // 启动计时器

	for (int x = 0; x < 1000; x++)
	{
		cout << x << endl;
	}
	timer.stop();          // 停止计时器


	const string fmt("挂起时间: %w 秒 \n用户CPU时间: %u 秒 \n系统CPU时间: %s 秒 \n总计CPU时间: %t 秒 \n利用率: %p(百分比)");

	cout << timer.format(3,fmt) << endl;
	getchar();
	return 0;
}