返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++11中的chrono库详解
  • 418
分享到

C++11中的chrono库详解

C++11中的chrono库C++11chrono库 2023-03-19 18:03:03 418人浏览 薄情痞子
摘要

目录前言1、记录时长的duration2、表示时间点的time_point3、获取系统时钟的clocks前言 c++11提供了日期时间相关的库chrono,通过chrono库可以很方

前言

c++11提供了日期时间相关的库chrono,通过chrono库可以很方便的处理日期和时间。chrono库主要包含3种类型:时间间隔duration、时钟clocks和时间点time_point

1、记录时长的duration

duration为一个模板类,表示时间间隔,可以是几秒、几分钟或者几个小时的时间间隔。duration的原型如下:

template <class Rep, 
class Period = ratio<1> >
class duration;

第一模板参数Rep是一个数值类型,表示时钟数的类型;第二个模板参数是一个默认模板参数std::ratio,表示时钟周期,它的原型如下:

template <intmax_t N, 
intmax_t D = 1
> class ratio;

它表示每个时钟周期的秒数,其中第一个模板参数N代表分子,D代表分母,分母默认为1,因此,ratio代表的是一个分子除以分母的分数值。比如:

ratio<2>	//代表2秒
ratio<60>	//代表1分钟
ratio<60*60>	//代表1小时
ratio<60*60*24>	//代表1天
ratio<1, 1000>	//代表1毫秒
ratio<1, 1000000>	//代表1微秒
ratio<1, 1000000000>	//代表1纳秒

为了方便使用,标准库定义了一些常用的时间间隔,如时、分、秒、毫秒、微秒和纳秒,在chrono命名空间下,定义如下(vs2013的源码):

typedef duration<long long, nano> nanoseconds;
typedef duration<long long, micro> microseconds;
typedef duration<long long, milli> milliseconds;
typedef duration<long long> seconds;
typedef duration<int, ratio<60> > minutes;
typedef duration<int, ratio<3600> > hours;

通过定义这些常用的时间间隔类型,我们能方便的使用它们,比如线程休眠:

//休眠100毫秒
this_thread::sleep_for(std::chrono::duration<int, ratio<1, 100>>(100));
this_thread::sleep_for(std::chrono::microseconds(100));//更简单

//休眠3秒
this_thread::sleep_for(std::chrono::duration<int>(3));
this_thread::sleep_for(std::chrono::seconds(3));//更简单

chrono还提供了获取时间间隔的时钟周期数的方法count(),它的基本用法如下:

#include<iOStream>
#include<chrono>
int main()
{
	std::chrono::seconds s(3);//3秒
	std::chrono::milliseconds ms = 2 * s;//6000毫秒
	std::cout << "3 s duration has " << s.count() << " ticks\n" << "6000 ms duration has " << ms.count() << " ticks\n";
}

执行结果:

在这里插入图片描述

duration在某些情况下可以进行转换,例如,当duration的Rep都为整型,且源Period要大于目标Period时或者目标duration的Rep为浮点数时可以使用传统类型转化或者隐式调用其单值构造函数,不必调用duration_cast

int main()
{
	//目标duration的Rep为double
	std::chrono::milliseconds int_milliseconds(1024);       // 1024ms
	std::chrono::microseconds int_microseconds(1024);       // 1024us
	std::chrono::duration<double> double_seconds;
	double_seconds = int_microseconds;	//1024ms = 1.024s
	double_seconds = int_milliseconds;	//1024us = 0.001024s


	//当duration的Rep都为整型,且源Period可被目标Period整除时
	int_microseconds = int_milliseconds; //ms赋值给us可以,但是us赋值给ms不可
	int_milliseconds = std::chrono::seconds(1);	//s赋值给ms可以,但是ms赋值给s不可以


	//源duration的Rep为double, 目标duration的Rep不为double,不能转换
	//std::chrono::milliseconds t1 = std::chrono::duration<double>(1024);


    std::chrono::seconds t1 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::milliseconds(1024));               // 1s = 1024ms(精度损失)
    std::chrono::seconds t2 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::duration<double>(1.024));          // 1s = 1.024s 
}

时间间隔之间可以做运算,计算两端时间间隔的差值的实例如下:

int main()
{
	std::chrono::minutes t1(10);
	std::chrono::seconds t2(50);
	std::chrono::seconds t3 = t1 - t2;
	cout << t3.count() << " second" << endl;
}

执行结果:

在这里插入图片描述

其中,t1代表10分钟,t2代表50秒,t3则是t1减t2,也就是600-50=550秒。通过调用t3的count()输出差值550个时钟周期,因为t3的时钟周期为1秒,所以t3表示时间间隔为550秒。

值得注意的是,duration的加减运算有一定的规则,当两个duration时钟周期不相同的时候,会先统一成一种时钟,然后再作加减运算。统一成一种时钟的规则如下:

对于ratio<x1, y1>count1和ratio<x2, y2>count2。如果x1、x2的最大公约数为x,y1、y2的最小公倍数为y,那么统一之后的ratio为ratio<x, y>

例如:

int main()
{
	std::chrono::duration<double, std::ratio<9, 7>> d1(3);
	std::chrono::duration<double, std::ratio<6, 5>> d2(1);
	auto d3 = d1 - d2;
	cout << "d3类型 : "<<typeid(d3).name() << endl;
	cout << d3.count() << endl;
}

执行结果:

在这里插入图片描述

根据前面介绍的规则,对于9/7和6/5,分子取最大公约数3,分母取最小公倍数35,所以,统一之后的duration为std::chrono::duration<double,struct std::ratio<3,35>>。然后再将原来的duration转换为统一的duration,最后计算的时钟周期数为:((9/7)/(3/35)*3)-((6/5)/(3/35)*1),结果为31

2、表示时间点的time_point

time_point表示一个时间点,用来获取从它的clock的开始所经过的duration(比如,可能是1970.1.1以来的时间间隔)和当前时间,可以做一些时间的比较和算术运算,可以喝ctime库结合起来显示时间。time_point必须用clock来计时。time_point有一个函数time_from_eproch()用来获得1970年1月1日到time_point时间经过的duration

time_point是一个类模板,原型如下:

template <class Clock, 
class Duration = typename Clock::duration>
class time_point;

template <class Clock, 
class Duration = typename Clock::duration>
class time_point;

第一个模板参数Clock用来指定所要使用的时钟(标准库中有三种时钟,system_clock,steady_clock和high_resolution_clock)
第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration<> )

计算当前时间距离1970年1月1日有多少天

#include<iostream>
#include<chrono>
#include<ratio>
using namespace std::chrono;
int main()
{
	using days_type = duration<int, std::ratio<60 * 60 * 24>>;
	time_point<system_clock, days_type> today = time_point_cast<days_type>(system_clock::now());
	std::cout << today.time_since_epoch().count() << " days since epoch" << endl;
}

执行结果:

在这里插入图片描述

time_point还支持一些算术运算,比如两个time_point的差值时钟周期数,还可以和duration相加减。要注意不同clock的time_point是不能进行算术运算的。下面例子将展示前一天和后一天的日期:

#include<iostream>
#include<chrono>
#include<iomanip>
using namespace std::chrono;
int main()
{
	system_clock::time_point now = system_clock::now();
	std::time_t prev = system_clock::to_time_t(now - hours(24)); //返回时间戳
	std::time_t next = system_clock::to_time_t(now + hours(24)); //返回时间戳

	cout << "One day aGo, the time was " << std::put_time(std::localtime(&prev), "%Y.%m.%d %H:%M:%S") << endl;
	cout << "A day later, the time is " << std::put_time(std::localtime(&next), "%Y.%m.%d %H:%M:%S") << endl;	 
}

执行结果:

在这里插入图片描述

3、获取系统时钟的clocks

clocks表示当前的系统时钟,内部有time_point、duration、Rep、Period等信息,主要用来获取当前时间,以及实现time_t和time_point的相互转换。clocks包含如下3种时钟:
-system_clock:代表真实时间的挂钟时间,具体时间依赖于系统。system_clock保证提供的时间值是一个可读时间
-steady_clock:不能被“调整” 的时钟,并不一定代表真实世界的挂钟时间。保证先后调用now()得到的时间值是不会递减的
-high_resoulution_clock:高精度时钟,实际上是system_clock或者steady_clock的别名。可以通过now()来获取当前时间点,代码如下:

int main()
{
	std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();
	cout << "hello fl" << endl;
	std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();
	cout << (t2 - t1).count() << " tick count" << endl;
	return 0;
}

执行结果:

在这里插入图片描述

system_clock的to_time_t方法可以将一个time_point转换为ctime:

std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);

而from_time_t方法则正好相反,它将ctime转换为time_point

steady_clock可以获取稳定可靠的时间间隔,后一次调用now()的值和前一次的差值不会因为修改了系统时间而改变,从而保证了稳定的时间间隔。steady_clock的用法和system用法一样。

到此这篇关于C++11中的chrono库详解的文章就介绍到这了,更多相关C++11中的chrono库内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++11中的chrono库详解

本文链接: https://lsjlt.com/news/200393.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++11中的chrono库详解
    目录前言1、记录时长的duration2、表示时间点的time_point3、获取系统时钟的clocks前言 C++11提供了日期时间相关的库chrono,通过chrono库可以很方...
    99+
    2023-03-19
    C++11中的chrono库 C++11 chrono库
  • C++11中的chrono库怎么使用
    本篇内容介绍了“C++11中的chrono库怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言C++11提供了日期时间相关的库chr...
    99+
    2023-07-05
  • C++11时间日期库chrono的使用
    目录时钟与时间点clock时间显示运行计时时间间隔durationduration模板duration_castratiochrono是C++11中新加入的时间日期操作库,可以方便地...
    99+
    2024-04-02
  • c++11 chrono的知识点有哪些
    这篇文章主要介绍“c++11 chrono的知识点有哪些”,在日常操作中,相信很多人在c++11 chrono的知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”c++11&nbs...
    99+
    2023-06-21
  • 详解C++11中的线程库
    目录一、线程库的介绍1.1. 使用时的注意点1.2. 线程函数参数1.3. join与detach二、原子性操作库2.1. atomic2.2. 锁三、使用lambda表达式创建多个...
    99+
    2024-04-02
  • C++11 中的override详解
    目录1 公有继承1.1 纯虚函数 (pure virtual)1.2 普通虚函数1.2.1 方法一1.2.2 方法二1.3 非虚函数2 重写 (override)小结:参考资料1 公...
    99+
    2024-04-02
  • 详解C++11中的类型推断
    C++11中的类型推断 C++11中为了更好的支持泛型编程,提供了 auto和decltype两个关键词,目的就是提供编译阶段的自动类型推导。 1.auto关键词的新意义 在C++9...
    99+
    2023-01-31
    C++11类型推断 C++11推断
  • C++11 中的std::function和std::bind详解
    目录1. 可调用对象2. std::function3. std::bind3.1 std::bind绑定普通函数3.2 std::bind绑定一个成员函数3.3 绑定一个引用参数4...
    99+
    2024-04-02
  • 一文详解C++11中的lambda函数
    目录1.lambda函数语法1.1 捕获列表1.2 mutable修饰符1.3 匿名lambda函数2.lambda与STL我可以明确告诉你:lambda函数是C++11中最重要的,...
    99+
    2023-02-07
    C++11 lambda函数使用 C++11 lambda函数 C++11 lambda
  • C++11 constexpr使用详解
    目录1.constexpr初探2.constexpr修饰函数的限制3.使用编译时对象4.constexprvsconst的区别C++11为了提高代码执行效率做了一些改善。这种改善之一...
    99+
    2024-04-02
  • 详解C++11中模板的优化问题
    1. 模板的右尖括号 在泛型编程中,模板实例化有一个非常繁琐的地方,那就是连续的两个右尖括号(>>)会被编译器解析成右移操作符,而不是模板参数表的结束。我们先来看一段关...
    99+
    2024-04-02
  • C++11中的变长模板的示例详解
    目录1.C99中的变长函数2.C++11中的变长函数3.详解变长模板3.1 更一般的SFINAE规则3.2 模板参数包的概念3.3 三个简单的例子3.4 函数参数包3.5 包扩展的进...
    99+
    2023-02-06
    C++11变长模板 C++ 变长模板 C++11 模板
  • C++11中std::function基础用法详解
    目录一、std::function基本介绍二、进阶使用方法2.1 与智能指针相结合2.2 存储成员函数指针2.3 存储std::bind三、注意tipsstd::function是C...
    99+
    2023-05-18
    C++11 std::function用法 C++11 std::function C++ std::function
  • C++11中异常处理机制详解
    目录一、异常的引入二、C++异常的关键字三、异常的抛出与处理规则四、异常缺陷的处理五、自定义异常体系六、异常规范七、异常安全八、异常的优缺点1.优点2.缺点一、异常的引入 传统的C语...
    99+
    2024-04-02
  • 详解C++11的std::addressof源码解析
    目录1、源码准备2、std::addressof简介3、std::addressof源码解析4、总结1、源码准备 本文是基于gcc-4.9.0的源代码进行分析,std::addre...
    99+
    2024-04-02
  • C++11中匿名函数lambda的使用详解
    目录一、lambda基础介绍二、lambda使用例子2.1 STL算法中的回调函数2.2 回调函数2.3 多线程编程三、总结官方介绍: C++ lambda是C++11新增的一种匿名...
    99+
    2023-05-18
    C++11匿名函数lambda使用 C++11匿名函数lambda C++11匿名函数
  • C++11原子操作详解
    目录C++11原子操作原子操作的概念示例总结C++11原子操作 原子操作的概念 所谓原子操作,其意义就是“原子是最小的,不可分割的最小个体”。**表示当多个线程访问同一个全局资源的时...
    99+
    2024-04-02
  • C++11新增的包装器详解
    目录functionbindfunction 目前,我们的知识深度已知的可调用对象类型有: 函数指针仿函数 / 函数对象lambda表达式 现在我们有一个函数模板 templa...
    99+
    2024-04-02
  • C++11中的线程库是什么
    小编给大家分享一下C++11中的线程库是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、线程库的介绍在C++11之前,涉及到多线程问题,都是和平台相关的,比...
    99+
    2023-06-29
  • 详解C++11中的线程锁和条件变量
    目录线程锁条件变量小结线程 std::thread类, 位于<thread>头文件,实现了线程操作。std::thread可以和普通函数和 lambda 表达式搭配使用。...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作