C++11提供时间管理类,包括三种类型:时间间隔duration,时钟clocks,时间点time point。

1、记录时常的duration

1.1 原型

  duration表示一段时间间隔,用来记录时间长度,可以表示时分秒等单位。其原型如下:

template<class Rep, class Period = std::ratio<, >> class duration;

  Rep表示一个数值类型,表示时钟数的类型,第二个参数表示始终周期。

  std::ratio原型如下:

template<std::intmax_t Num, std::intmax_t Denom = > class ratio;

  std::ratio表示时钟周期的秒数,Num表示分子,Denom表示分母,分母默认为1,分数值表示秒数。

ratio<>          //2秒
ratio<> //一分钟
ratio<*> //一小时
ratio<**> //一天
ratio<, > //一毫秒
ratio<, > //一微秒
ratio<, > //一纳秒

  标准库还定义了一些常用的时间间隔:

typedef duration<Rep, ratio<, >> hours;
typedef duration<Rep, ratio<, >> minutes;
typedef duration<Rep, ratio<, >> seconds;
typedef duration<Rep, ratio<, >> milliseconds;
typedef duration<Rep, ratio<, >> microseconds;
typedef duration<Rep, ratio<, >> nanoseconds;

  可以通过常用类型来使用到我们代码中,如线程休眠:

std::this_thread::sleep_for(std::chrono::seconds());         //休眠3秒
std::this_thread::sleep_for(std::chrono::milliseconds()); //休眠100毫秒

1.2 运算

1.2.1 统计

  chrono提供获取时间间隔的时钟周期的方法count()。

#include <iostream>
#include <chrono> using namespace std; int main()
{
//3毫秒
std::chrono::milliseconds ms{};
std::cout << "3 ms duration has " << ms.count() << " ticks." << std::endl; //通过3毫秒初始化6000微秒
std::chrono::microseconds us = *ms;
std::cout << "6000 us duration has " << us.count() << " ticks." << std::endl; //自定义一个时钟周期
std::chrono::duration<double, std::ratio<, >> hz30{3.5};
std::cout << "3.5 hz duration has " << hz30.count() << " ticks." << std::endl; return ;
} //执行结果
ms duration has ticks.
us duration has ticks.
3.5 hz duration has 3.5 ticks.

1.2.2 间隔运算

  时间间隔可以做运算,计算两段时间的差值。

std::chrono::minutes t1{};        //10分钟
std::chrono::seconds t2{}; //60秒
std::chrono::seconds t3 = t1 - t2; std::cout << t3.count() << " seconds." << std::endl;
//输出
seconds.

  duration也有一套自己的运算规则,当两个duration始终周期不同的时候,会统一成一种时钟,然后再做运算。其规则如下:

  对于ratio<x1, y1> r1,ratio<x2, y2> r2;如果x1、x2最大公约数为x,y1、y2最大公约数为y,那么统一之后的ratio为ratio<x,y>。

#include <iostream>
#include <chrono>
#include <typeinfo> using namespace std; int main()
{
std::chrono::duration<double, std::ratio<, >> d1{};
std::chrono::duration<double, std::ratio<, >> d2{};
auto d3 = d1 - d2; std::cout << "typeid:" << typeid(d3).name() << std::endl;
std::cout << d3.count() << std::endl; return ;
}
//执行结果
typeid:std::chrono::duration<double, std::ratio<, >>

  根据规则,7/9和6/5,分子最大公约数为3,分母最小公倍数为35,所以统一之后的duration为std::chrono::duration<double, std::ratio<3, 35>>,所以始终周期为((7/9)/(3/35)*3) - ((6/5)/(3/35)*1) = 31。

1.2.3 转换

  可以通过duration_cast<>()来将当前的时钟周期转换为其它的时钟周期。

//将秒转换为分钟数
std::chrono::seconds ts{};
std::cout << std::chrono::duration_cast<std::chrono::minutes>(ts).count() << " minutes." << std::endl;
//执行结果
minutes.

2、时间点的表示

  time_point表示一个时间点,用来获取从它的clock的纪元开始所经过的duration(比如从1970.1.1开始计算)和当前的时间。time_point可以和ctime结合起来显示时间,必须用clock来计时。time_point有一个函数time_from_eproch()用来获得纪元到time_point时间经过的duration。

#include <iostream>
#include <chrono> using namespace std;
using namespace std::chrono; int main()
{
typedef duration<int, ratio<**>> days_type; time_point<system_clock, days_type> today = time_point_cast<days_type>(system_clock::now()); cout << today.time_since_epoch().count() << endl; return ;
}
//执行结果

  time_point还支持一些算术运算,比如两个time_point的差值时钟周期数,还可以和duration相加减,但是必须是相同的clock。

#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip> using namespace std;
using namespace std::chrono; int main()
{
typedef duration<int, ratio<**>> days_type; system_clock::time_point now = system_clock::now();
time_t last = system_clock::to_time_t(now - hours());
time_t next = system_clock::to_time_t(now - hours()); cout << "last day: " << put_time(localtime(&last), "%c") << endl;
cout << "next day: " << put_time(localtime(&next), "%c") << endl; return ;
}
//执行结果
last day: // ::
next day: // ::

3、获取系统时钟的clocks

  • clocks表示当前的系统时钟,内部有time_point、duration、Rep、Period等信息,主要用来获取当前时间,以及事项time_t和time_point的相互转换。clocks包括如下三种时钟:
  • system_clock:表示真实世界的挂钟时间,具体时间依赖于系统。
  • steady_clock:不能被“调整”的时钟,并不一定代表真实世界的挂钟时间,保证先后调用now()的得到的时间值是不会递减的。
  • high_resolution_clock:高精度时钟,实际上system_clock或者steady_clock的别名,可以通过nowlai 获取当前的时间点。
#include <iostream>
#include <chrono> using namespace std;
using namespace std::chrono; int main()
{
system_clock::time_point t1 = system_clock::now();
cout << "hello world." << endl;
system_clock::time_point t2 = system_clock::now();
cout << (t2-t1).count() << " tick count."<< endl; return ;
}
//执行结果:
hello world.
tick count.

  通过时钟获取的两个时间点之间差多少个时钟周期,可以通过duration_cast来将其转换为其他时钟周期的duration:

cout << duration_cast<microseconds> (t2-t1).count() << " microseconds."<< endl;
//输出结果:
hello world.
microseconds.

  system_clock的to_time_t可以将一个time_point转换为ctime,而from_time_t方法则可以将ctime转换为time_point。

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

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

  system_clock和std::put_time配合起来使用可以格式化日期的输出。

#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono> using namespace std;
using namespace std::chrono; int main()
{
auto t = system_clock::to_time_t(system_clock::now()); cout << put_time(localtime(&t), "%Y-%m-%d %X") << endl;
cout << put_time(localtime(&t), "%Y-%m-%d %H.%M.%S") << endl; return ;
}
//执行结果:
-- ::
-- 21.19.

4、计时器timer

  可以利用high_resolution_clock来实现一个类似于boost.timer的计时器,这样的timer在测试性能的时候经常用到。在程序日常开发的时候可以作为测试函数耗时。

void func()
{
//dosomething...
} int main()
{
Timer t; //开始计时
func();
cout << t.elapsed() << endl; //打印func函数耗时
}

  C++中可以通过chrono库来事项一个计时器,从而移除对其他三方库的依赖。

#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono> using namespace std;
using namespace std::chrono; class CTimer
{
public:
CTimer() : m_begin(high_resolution_clock::now()) {} //重置
void mvReset() { m_begin = high_resolution_clock::now(); } //默认输出毫秒
template<typename Duration = milliseconds>
int64_t elapsed() const
{
return duration_cast<Duration>(high_resolution_clock::now() - m_begin).count();
} //微秒
int64_t elapsed_micro() const
{
return elapsed<microseconds>();
} //纳秒
int64_t elapsed_nano() const
{
return elapsed<nanoseconds>();
} //秒
int64_t elapsed_sconds() const
{
return elapsed<seconds>();
} //分
int64_t elapsed_minutes() const
{
return elapsed<minutes>();
} //时
int64_t elapsed_hours() const
{
return elapsed<hours>();
} private:
time_point<high_resolution_clock> m_begin;
}; //test func
void func()
{
cout << "hello world." << endl;
} int main()
{
CTimer t;
func();
cout << t.elapsed() << endl; //打印func函数耗时毫秒
cout << t.elapsed_micro() << endl; //打印func函数耗时微秒
cout << t.elapsed_nano() << endl; //打印func函数耗时纳秒
cout << t.elapsed_sconds() << endl; //打印func函数耗时秒
cout << t.elapsed_minutes() << endl; //打印func函数耗时分
cout << t.elapsed_hours() << endl; //打印func函数耗时小时 return ;
}
//执行结果
hello world.

C11工具类:时间处理的更多相关文章

  1. C11工具类:字符转换

    1.数值类型和字符串转换 1.1 数值转换为字符 std::string to_string(int value); std::string to_string(long value); std::s ...

  2. 代码片段:基于 JDK 8 time包的时间工具类 TimeUtil

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “知识的工作者必须成为自己时间的首席执行官.” 前言 这次泥瓦匠带来的是一个好玩的基于 JDK ...

  3. android开发时间和日期的代码实现工具类(一)

    android开发时间和日期工具类的代码实现: package com.gzcivil.utils; import android.annotation.SuppressLint; import an ...

  4. Java日期工具类,Java时间工具类,Java时间格式化

    Java日期工具类,Java时间工具类,Java时间格式化 >>>>>>>>>>>>>>>>>&g ...

  5. 使用java的Calendar工具类获取到本月的第一天起始时间和最后一天结束时间。

    1.使用java的Calendar工具类获取到本月的第一天起始时间和最后一天结束时间. package com.fline.aic.utils; import java.text.DateFormat ...

  6. 小记Java时间工具类

    小记Java时间工具类 废话不多说,这里主要记录以下几个工具 两个时间只差(Data) 获取时间的格式 格式化时间 返回String 两个时间只差(String) 获取两个时间之间的日期.月份.年份 ...

  7. [java工具类01]__构建格式化输出日期和时间的工具类

    在之前的学习中,我写过一篇关于字符串格式化的,就主要设计到了时间以及日期的各种格式化显示的设置,其主要时通过String类的fomat()方法实现的. 我们可以通过使用不同的转换符来实现格式化显示不同 ...

  8. 超详细的Java时间工具类

    package com.td.util; import java.sql.Timestamp; import java.text.ParseException; import java.text.Pa ...

  9. java后端时间处理工具类,返回 "XXX 前" 的字符串

    转自:https://www.cnblogs.com/devise/p/9974672.html 我们经常会遇到显示 "某个之间之前" 的需求(比如各种社交软件,在回复消息时,显示 ...

随机推荐

  1. 自测之Lesson6:文件I/O

    题目:区分文件I/O和标准I/O. 区别: ①首先两者一个显著的不同点在于,标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区), ...

  2. 软件管理——rpm&dpkg、yum&apt-get

    一般来说著名的linux系统基本上分两大类: 1. RedHat系列:Redhat.Centos.Fedora等 2. Debian系列:Debian.Ubuntu等 一.RedHat 系列     ...

  3. iOS开发UUIView动画方法总结

    #动画设置 UIView动画实现 @interface ViewController () @property (weak, nonatomic) IBOutlet UIView *myView; @ ...

  4. 浅谈 Vue v-model指令的实现原理 - 如何利用v-model设计自定义的表单组件

    原文请点击此链接  链接1 http://www.7zhang.com/index/cms/read/id/234515.html  链接2 http://blog.csdn.net/yangbing ...

  5. mstsc远程登录终端超出最大连接数的解决办法

    1,.远程服务器有两个用户登录 2.第三个登录时提示:终端服务器超出了最大允许连接,这种情况怎么解决 A.通过运行命令来解决:运行输入mstsc /admin /v:IP:端口  敲回车来解决,这里的 ...

  6. CSS设计指南之一 HTML标记与文档结构

    HTML标记与文档结构 之所以从HTML讲起,是因为CSS的用途就是为HTML标记添加样式. 1.1 HTML标记基础 对于每个包含内容的元素,根据它所包含的内容是不是文本,有两种不同的方式给它们加标 ...

  7. 能选择日期范围js控件

    html页面中使用日期控件是常有的事,好控件能使用开发变的快捷,下面是在开发过程中发现的几款日期控件,比较不错,收藏 1.基于bootstrap的jQuery日期范围选择插件 2.jQuery多功能日 ...

  8. BZOJ 1022 小约翰的游戏(anti-sg)

    这是个anti-sg问题,套用sj定理即可解. SJ定理 对于任意一个Anti-SG游戏,如果定义所有子游戏的SG值为0时游戏结束,先手必胜的条件: 1.游戏的SG值为0且所有子游戏SG值均不超过1. ...

  9. 【bzoj1572】[Usaco2009 Open]工作安排Job 贪心+堆

    题目描述 Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有1000000000个单位时间(!). ...

  10. Luogu1053 NOIP2005篝火晚会

    首先造出所要求的得到的环.如果将位置一一对应上,答案就是不在所要求位置的人数.因为显然这是个下界,并且脑补一下能构造出方案达到这个下界. 剩下的问题是找到一种对应方案使错位数最少.可以暴力旋转这个环, ...