文档章节

C++11: chrono

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/05/08 20:49
字数 2171
阅读 199
收藏 1
点赞 2
评论 0

chrono是一个time-library,要使用chrono这个库需要#include<chrono>.

通常要使用chrono这个库必定少不了ratio这个库,需包含#include<ratio>,如果已经#include<chrono>就不需要再#include<ratio>了.

 

我们首先来明确两个概念:

所谓duration(时间段): 指的是在某时间单位上的一个明确的tick(片刻数).举个例子,“3分钟”指的是“3个一分钟”。

所谓timepoint(时间点):的意思是一个duration和一个epoch(起始点)的组合. 典型的例子是“2000年新年午夜”时间点,它被描述为“自1970年1月1日开始的第1 262 300 400秒”。

ratio:

 template <intmax_t Numerator, intmax_t Denominator = 1> class ratio;

Numerator:  分子.

Denominator: 分母.

ratio有两个成员:

ratio::num; //获得ratio的分子.

ratio::den; //获得ratio的分母.

#include <iostream>
#include <ratio>
int main()
{
 std::ratio<1, 4> oneForth;
 std::cout<<"Numrator: "<<oneForth.num<<std::endl; //输出: 1.
 std::cout<<"Denominator: "<<oneForth.den<<std::endl; //输出: 4.
 
 return 0;
}

 

std::chrono::duration

用来表示一段时间.

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

Rep: 是一个算术类型(int, double....),或者一类模拟算术类型.

Period: 是一个std::ratio类型.

比如:

 std::chrono::duration<int, std::ratio<1,1>> seconds(3);//3秒.

由于各种duration的表示是不同的(比如不同的std::duration,用的std::ratio是不同的)因此标准库还提供了:

template <class ToDuration, class Rep, class Period>
  constexpr ToDuration duration_cast (const duration<Rep,Period>& dtn);

ToDuration: 是我们想要转成duration的类型.

Rep: 是将要被我们转换的duration类型的算术类型.

Period: 是将要被我转换的duration类型的std::ratio类型.

duration的成员函数:

 constexpr rep count() const;

返回该duration中std::ratio的数量.

 static constexpr duration zero();

返回长度为0的duration.

 

 static constexpr duration min();

返回此类型之最小的可能.

 

 static constexpr duration zero();

返回此类型之最大的可能.

 

#include <iostream>
#include <ratio>
#include <chrono>
int main()
{
 using second_type = std::chrono::duration<int, std::ratio<1, 1>>;
 using minutes_type = std::chrono::duration<int, std::ratio<60, 1>>;
 using hour_type = std::chrono::duration<int, std::ratio<3600, 1>>; 
 
 second_type oneDay1(24*3600); //一天:24*3600秒. 
 minutes_type oneDay2(24*60); //一天: 24*60分钟. 
 hour_type oneDay3(24);      //一天: 24小时. 
 
 //hour_type oneDay4(oneDay2); //error.不能直接转换. 
 hour_type oneDay5(oneDay3); // ok.
 hour_type oneDay6(std::chrono::duration_cast<hour_type>(oneDay2)); //ok.
 
 std::cout<< oneDay3.count() <<std::endl; //输出: 24.
 hour_type threeDay = oneDay3 * 3;        // 3天: 3*24 
 std::cout<< threeDay.count() <<std::endl;//输出: 3 * 24. 
 
 
 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); //获取当前时间. 
 std::cout<< "Print something..."<<std::endl;
 std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); //获取当前时间. 
 std::chrono::steady_clock::duration d = t2 - t1; //计算出std::cout<<"Print something..."<<std::endl;花费的时间. 
 //注意上面使用的是steady_clock中的duration. 
 if(d == std::chrono::steady_clock::duration::zero()){  //判断这段时间是不是为0. 
  std::cout<<"The interal clock did not tick\n"<<std::endl;
  
 }else{
  std::cout<<"The interal clock advanced! "<< d.count() <<std::endl;
  
 }
 
 
 using namespace std::chrono;
 milliseconds ms(7255042);
 
 hours hh = duration_cast<hours>(ms);
 minutes mm = duration_cast<minutes>(ms % hours(1)); //注意这里ms是个std::chrono::milliseconds类型. 
 seconds ss = duration_cast<seconds>(ms % minutes(1));
 std::cout<<"hours: "<<hh.count()<<" minutes: "<<mm.count()<<" seconds: "<<ss.count()<<std::endl;
 
 return 0;
}

 

Clock:

Clock定义出了一个epoch(起始点)和一个tick(周期,也可以称作period).例如某个Clock也许定义周期(tick)为毫秒(millionsecond),起始点是UNIX epoch(起始点): 1970年1月1日, 或者定义周期(tick)为纳秒(nanosecond),起始点为程序员的开始时间.

Clock还提供了一个类型给“与此Clock关联”的任何timepoint使用,例如Clock的now()成员函数可以产出一个代表“现在时刻”的timepoint对象.

 

Clock(时钟)有三种:

std::system_clock;  //它所表现的timepoint(时间点)将关联到现行系统的即时时钟.这个clock提供便捷函数to_time_t()和from_time_t(),允许我们在timepoint和C语言的系统时间类型time_t之间转换。

std::steady_clock;  //它保证绝对不会被调整。因此当实际时间流逝,其timepoint值也绝对不会减少,而且这些timepoint对于真实时间都有稳定的前进速率.

std::high_resolution_clock;  //它表现的是当前系统中带有最短tick(周期)的clock.(我们常用的时间周期是1秒).也就是说它是更高精度的std::steady_clock

注意,标准库并不强制规定各种clock的精确度, epoch(起始点), "最大和最小的timepoint的范围"

 以上3种Clock都具有的成员类型:

Clock::duration  //获得Clock的duration(时间段)类型.因为一般情况下我们是不知道Clock的计时单位的因此用这个比较保险.

Clock::rep  //获得上面得到的duration的算术类型比如是:double啊,int啊,等等,等价于:Clock::duration::rep

Clock::period //获得当前Clock的duration类型的,计时单位,是分? 是秒?其实也就是一个std::ratio类型.

也相当于Clock::duration::period.

Clock::is_steady //如果该Clock是一个steady类型,该值为true.

Clock::now()  //一个static函数,获得调用该函数时候的当前时刻.

 

 #include <iostream>
#include <chrono>
#include <type_traits>
template<typename Clock, typename = typename std::enable_if< std::is_same<Clock, std::chrono::steady_clock>::value
                                                          || std::is_same<Clock, std::chrono::system_clock>::value
                      || std::is_same<Clock, std::chrono::high_resolution_clock>::value
                      >::type>
void printClockData()
{
 std::cout<<"- precision: ";
 using P = typename Clock::period; //相当于Clock::duration::period;其实是一个std::ratio类型.
 
 if(std::ratio_less_equal<P, std::milli>::value){
  using TT = typename std::ratio_multiply<P, std::kilo>::type; //这里的type是std::ratio类型.
  std::cout<< std::fixed << double(TT::num)/TT::den << " milliseconds " << std::endl; 
  
 }else{
  std::cout<< std::fixed << double(P::num)/P::den <<" seconds"<<std::endl;
 } 
 
 std::cout<<"- is_steady: "<< std::boolalpha << Clock::is_steady << std::endl;
}
int main()
{
 std::cout<< "system_clock: " <<std::endl;
 printClockData<std::chrono::system_clock>();
 std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();
 std::cout<< "system_clock::now() "<<std::endl;
 std::chrono::system_clock::duration sd = std::chrono::system_clock::now() - t1;
 std::cout<< "cost: "<< sd.count() <<std::endl; //输出: 0 
 
 
 std::cout<< "\nhigh_resolution_clock: "<<std::endl;
 printClockData<std::chrono::high_resolution_clock>();
 std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
 std::cout<< "high_resolution_clock::now() " <<std::endl;
 std::chrono::high_resolution_clock::duration hd = std::chrono::high_resolution_clock::now() - t2;
 std::cout<< "cost: "<< hd.count() <<std::endl; //输出: 0
 
 std::cout<< "\nsteady_clock: "<<std::endl;
 printClockData<std::chrono::steady_clock>();
 std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now();
 std::cout<< "steady_clock::now() "<<std::endl;
 std::chrono::steady_clock::duration ssd = std::chrono::steady_clock::now() - t3;
 std::cout<<"cost: "<< ssd.count() <<std::endl;
 
 std::chrono::duration<std::chrono::steady_clock::rep, std::chrono::steady_clock::period> du = ssd;
 std::chrono::steady_clock::period ratioForSteady_clock;
 std::cout<< ratioForSteady_clock.num << " " << ratioForSteady_clock.den <<std::endl;
 
 return 0;
}

 

Timepoint(时间点):

夹带(搭配)那些clock,甚至用户自定义的clock,你将可以处理timepoint。Class time_point提供了相应接口,以一个clock为参数.

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

下面4个特定的timepoint扮演了特殊的角色.

1,Epoch, 由任何clock的time_point的default构造函数产出.

2,Current time, 由任何clock的static成员函数now()产出.

3,Minimnum timepoint, 由任何clock的timepoint的static成员函数min()产出.

4,Maximum timepoint, 由任何clocktimepoint的static成员函数max()产出.

#include <iostream>
#include <chrono>
#include <ctime>
#include <string>

std::string asString(const std::chrono::system_clock::time_point& tp)
{
	std::time_t t = std::chrono::system_clock::to_time_t(tp);
	std::string timeString = std::asctime(std::gmtime(&t));
	//timeString.resize(timeString.size()-1);
	return timeString;
} 

int main()
{
	std::chrono::system_clock::time_point tp;
	std::cout<< "epoch: "<< asString(tp) <<std::endl;
	
	tp = std::chrono::system_clock::now();
	std::cout<< "now: "<< asString(tp) <<std::endl;
	 
	/*tp = std::chrono::system_clock::time_point::min();
	std::cout<< "min: "<< asString(tp) <<std::endl;*/ //这种情况下是不行的不能得到最小时间点(timepoint).
	
	//使用 std::chrono::time_point_cast; 
	using userDefined = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int, std::micro>>;
	userDefined tp1 = std::chrono::time_point_cast<std::chrono::duration<int, std::micro>>(std::chrono::system_clock::time_point::min());
	std::cout<< "min: "<< asString(tp1) <<std::endl;
	
	
	//使用 std::chrono::time_point的构造函数. 
	std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<int>> t_p;
	std::chrono::system_clock::time_point tp2(t_p);
	tp2 = std::chrono::system_clock::time_point::max();
	std::cout<< "max: "<< asString(tp2)<<std::endl;
	
	return 0;
}

std::chrono::time_point的operator(s):

#include <iostream>
#include <ctime>
#include <chrono>
#include <string>

std::string asString(const std::chrono::system_clock::time_point& tp)
{
	std::time_t t = std::chrono::system_clock::to_time_t(tp);
	
	std::string timeString(std::ctime(&t));
	return timeString;
}

int main()
{
	using Days = std::chrono::duration<int, std::ratio<3600*24>>; 
	using Hours = std::chrono::duration<int, std::ratio<3600>>;
	using Minutes = std::chrono::duration<int, std::ratio<60>>;
	using Seconds = std::chrono::duration<int, std::ratio<1,1>>;
	using Years = std::chrono::duration<unsigned long long, std::ratio<3600*24*365>>;
	
	
	
	std::chrono::time_point<std::chrono::system_clock> tp1;  
	std::cout<< "Epoch: "<< asString(tp1) <<std::endl;  //等同于: asString(std::chrono::system_clock::time_point()); 
	
	//加1天,23小时,55分钟.
	tp1 += Days(1) + Hours(23) + Minutes(55);
	std::cout<<"Later: " << asString(tp1) << std::endl;
	
	std::chrono::duration<std::chrono::system_clock::rep, std::chrono::system_clock::period> dis = tp1 - std::chrono::system_clock::time_point();
	//注:上面减号后面的 std::chrono::system_clock::time_point();获得的是Epoch.
	 std::cout<< "Diff:    "
	          << (std::chrono::duration_cast<std::chrono::minutes>(dis)).count()
	          << " minute(s)." <<std::endl;
	Days days = std::chrono::duration_cast<Days>(dis);
	std::cout<< "days:    "
	         << days.count() << " day(s)."<<std::endl;
	         
    tp1 -= Days(365); //该时间点往前推移一年.
	std::cout<< "-1 year:   " << asString(tp1) <<std::endl; 
	
	tp1 -= Years(50); //该时间点往前推移五十年.
	std::cout<< "-50 years:  " << asString(tp1) <<std::endl;
	 
	tp1 -= Years(50); //该时间点往前推移五十年.
	std::cout<< "again -50 years:  " << asString(tp1) <<std::endl;
	
	
	return 0; 
	
}

16/6/21:

两种打印时间字符串的方法:

#include <iostream>
#include <chrono>
#include <ratio>

int main()
{
	//case 1: 这种情况下是考虑时区的. 
	std::chrono::time_point<std::chrono::system_clock> tp; //epoch
	std::time_t t = std::chrono::system_clock::to_time_t(tp);
	std::string strOne = std::ctime(&t);
	strOne.resize(strOne.size()-1);  //去除尾部的换行符. 
	std::cout<< strOne << std::endl;
	
	//case 2: 不考虑时区. 
	std::chrono::time_point<std::chrono::system_clock> tp_one; //epoch
	std::time_t tTwo = std::chrono::system_clock::to_time_t(tp_one);
	std::string strTwo = std::asctime(std::gmtime(&tTwo));
	std::cout<< strTwo <<std::endl;
	
	
	return 0;
}

 

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 12
博文 165
码字总数 138772
作品 0
武汉
程序员
c++11实现异步定时器

c++11提供了丰富的时间和线程操作函数,比如 std::this_thread::sleep, std::chrono::seconds等。可以利用这些来很方便的实现一个定时器。 实现 ifndef TIMERH define TIMERH include includ...

moki_oschina
05/23
0
0
C++:获取时间戳

文中代码主要来自 http://stackoverflow.com/questions/6012663/get-unix-timestamp-with-c http://stackoverflow.com/questions/19555121/how-to-get-current-timestamp-in-milliseconds-si......

樂天
2016/06/29
923
0
使用 C++11 的线程

除了使用 的方式创建新线程,还可以使用 C++11 的线程 thread 类。 示例 编译后运行 查看进程和线程 ID 可以看到有 testThread 进程在运行,进程中有两个线程 8083 和 8085 在运行。...

兔之
2016/12/06
7
0
C++11 std::chrono库详解

复制代码 2.Time pointsstd::chrono::time_point 表示一个具体时间,如上个世纪80年代、你的生日、今天下午、火车出发时间等,只要它能用计算机时钟表示。鉴于我们使用时间的情景不同,这个t...

moki_oschina
05/23
0
0
C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量

上一篇文章中我们学习了如何使用互斥量来解决一些线程同步问题。这一讲我们将进一步讨论互斥量的话题,并向大家介绍 C++11 并发库中的另一种同步机制 —— 条件变量。 递归锁 考虑下面这个简...

天下杰论
2013/12/29
0
0
基于 libevent 开发的 C++ 11 高性能网络服务器--evpp

evpp是一个基于libevent开发的现代化C++11高性能网络服务器,自带TCP/UDP/HTTP等协议的异步非阻塞式的服务器和客户端库。 特性: 现代版的C++11接口 非阻塞异步接口都是C++11的functional/bi...

zieckey
2017/03/06
6K
16
提升 C++ 技能的 7 种方法

本文由伯乐在线 -精算狗 翻译,艾凌风 校稿。未经许可,禁止转载! 英文出处:Jonathan Boccara。欢迎加入翻译组。 夏天时常会谈到大海、太阳、沙滩、大山或者你的家庭住宅。更充裕的时间也是...

伯乐在线
2017/08/24
0
0
Android NDK 替代方案--CrystaX NDK

CrystaX NDK是Google's Android NDK的一个替代方案.相比谷歌的NDK, CrystaX NDK在支持相同功能的同时, 提供了一些很棒的新功能和大量的缺陷修复和改进. CrystaX NDK的主要目的是让Android开发...

zjzdy
2015/07/25
1K
1
【C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量(bill译)】

C++11 并发编程教程 - Part 3 : 锁的进阶与条件变量 注:文中凡遇通用的术语及行话,均不予以翻译。译文有不当之处还望悉心指正。 原文:C++11 Concurrency Tutorial – Part 3: Advanced l...

技术小胖子
2017/11/02
0
0
基于事件驱动状态机的协程框架设计

在设计协程之前,先将几个小概念 并发: 最早的计算机,每次只能执行一个程序,只有当当前执行的程序结束后才能执行其它程序,在此期间,别的程序都得等着。到后来,计算机运行速度提高了,程...

Sean-x
2016/07/11
271
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
12分钟前
0
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
18分钟前
0
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
33分钟前
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
40分钟前
0
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
47分钟前
0
0
开发技术瓶颈期,如何突破

前言 读书、学习的那些事情,以前我也陆续叨叨了不少,但总觉得 “学习方法” 就是一个永远在路上的话题。个人的能力、经验积累与习惯方法不尽相同,而且一篇文章甚至一本书都很难将学习方法...

_小迷糊
48分钟前
0
0
安装tensorflow-XXX报错

报错: tensorflow-0.5.0-cp27-none-linux_x86_64.whl is not a supported wheel on this platform. 解决: wget https://bootstrap.pypa.io/get-pip.py sudo python2.7 get-pip.py sudo p......

Yao--靠自己
51分钟前
0
0
JVM学习手册(一):JVM模型

一直从事JAVA开发,天天和JVM打交道,仔细想想对JVM还真的不是特别了解,实在是不应该.周六看了许多资料,也算有点心得,记录一下。 JVM内存模型分为5个区域:方法区,堆,虚拟机栈,本地方法栈,程序计...

勤奋的蚂蚁
今天
0
0
转行零基础该如何学Python?这些一定要明白!

转行零基础学Python编程开发难度大吗?从哪学起?近期很多小伙伴问我,如果自己转行学习Python,完全0基础能否学会呢?Python的难度到底有多大?今天,小编就来为大家详细解读一下这个问题。...

猫咪编程
今天
2
0
205. Isomorphic Strings - LeetCode

Question 205. Isomorphic Strings Solution 题目大意:判断两个字符串是否具有相同的结构 思路:构造一个map,存储每个字符的差,遍历字符串,判断两个两个字符串中相同位置字符的差是否相同 Ja...

yysue
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部