【C++标准库】std::chrono

【C++标准库】std::chrono,

编程语言最该拥有. 最不可或缺的程序库,应该是用来处理日期和时间的程序库。然而经验显示,这样 的程序库远比想象中难设计。问题出在它应该提供多少弹性和多少精度。事实上,在过去, C和POSIX提供的 系统时间(system time)接口,允许从秒转换做亳秒(millisecond) , 再至微秒(microsecond), 最终至纳秒(nanosecond), 问题是每次转换就需要一个新接口。基于这个原因,C++11开始提供一个精度中立(precision-neutral)的程序库,它常被称为chrono程序库, 为它的特性被定义于。
此外C++标准库也提供一个基本的C和POSIX接口,用来处理日历时间。你也可以使用自C++11的thread的程序库。等待某个线程或程序(主线程)一 段时间。

引入几个概念:

  • duration(时间段)
  • timepoint(时间点)
  • tick(片刻数)
  • epoch(起点,重要纪元)
  • clock(时钟)

解释一下:

– duration(时间段) = tick(片刻数)* (分,秒,毫秒,1/3秒)时间单位,如3分钟 = 3个* 1分钟,或者2个*1.5分钟;所以这个时间单位,并不是规定好的 。

– timepoint(时间点) = epoch(起始点) + duration(时间段)。2000年新年午夜(timepoint) =1970年1月1日(epoch)+ 1262300400秒(duration)

– epoch(时间点),不同的clock(时钟)有不同的epoch(起点)。一般而言,处理两个timepoint之间的差距时,必须采用相同的epoch/clock。

0.ratio精度

时钟节拍(时间精度):

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

其中N表示分子,D表示分母,默认用秒表示的时间单位。

N对应于其成员num,D对应于其成员den

这里有一个模板类ratio<num ,den >,作用就是一个时间单位。(可以是0.5秒,1.5秒的非整数)

ratio<60, 1> minute

ratio<1, 1> second

ratio<1, 1000> microsecond

1.Duration

1.1先看怎么用duration构建时间段对象。

std::chrono::duration<int> twentySeconds(20); 
std::chrono::duration<double, std::ratio<60>> halfAMinute (0.5); 
std::chrono::duration<long,std::ratio<l,1000>>oneMillisecond(l);

duration模板有两个template参数,第一个(tick)片刻个数,第二个ratio<60,1>是时间单位。

所以,
   第一个duration<int>,指明片刻个数是整形,默认单位是1秒, twentySeconds(20)创建对象初始化20秒。
   第二个duration<double, std::ratio<60>>,片刻个数可以是小数 halfAMinute (0.5)0.560秒。
   第三个同理。。

1.2 C++标准库定义好的时间段类型

C++ 给我们封装好了不同的时间段类型,

image-20221101204602701

例如:

typedef duration<signed int-type>= 29 bits, ratio<6>>   minutes;

我们知道typedef作用,给类起别名。类minutes 就是 duration= 29 bits, ratio<6>>。

所以创建时间段对象,可以直接用 minutes 对象名

std: : chrono: : minutes twentyMinutes(20); //就可以得到一个20分钟的对象。 

所以,我们除了可以用std::chrono::duration自己指定一个时间段类型,还可以用标准库中内置的 minutes,seconds时间段类型。

1.3 Duration的算数运算

时间段 可以 进行:

  • 加 d1 +d2

  • 减 d1-d2

  • 乘 d*val

  • 除 d/val

  • 比较大小 d1<d2

  • 等等。。。

    这里的关键是 ,两个变量的类型可以不一样。列如

    image-20221101205442135

1.4 Duration转换单位(不同的时间片)

可以将duration转化成不同的单位,只有彼此之间存在隐式转换就行。

可以将小时转换 成秒,反向不行。

#include<iostream>
#include<chrono>
using namespace std;

int main()
{
    
    
    // 创建时间段 对象
    std::chrono::seconds twentySeconds(20); //20秒
    std::chrono::hours   oneDay(24); //一天24小时
    std::chrono::milliseconds ms(0);//0毫秒
    // 算数操作+隐式转换
    ms += oneDay+twentySeconds;// 86 400 000+ 20 000 = 86420 000 milliseconds;
    --ms;                      // 86419999milliseconds;
    ms *= 2;                  // 172839998 milliseconds;
    //打印
    cout<<ms.count()<<"ms"<<endl;
    cout<<std::chrono::nanoseconds(ms).count()<<"ms"<<endl;//ms 转换成纳秒,并显示
    system("pause");
    return 0;
}
172839998ms
172839998000000ms 
Press any key to continue . . . 

1.5 duration总结

image-20221101210353736

上面有一些成员属性,以及函数,有C++基础的应该都能看懂。

2.Clock(时钟)和TimePoint(时间点)

前面提到,epoch(起点)和clock相关。

实际上,clock不只影响epoch(起始点),同时不同的clock会有不同的tick周期(时间单位),

例如某个clock,定义起点是1970年一月一日的epoch,周期是 毫秒milliseconds。

2.1 Clock时钟

image-20221101212549514

C++ 标准库提供了三个clock

  • 1 system_clock
    • 它所表现的timepoint将关联至现行系统的即时时钟(real-time clock)这个clock提供便捷函数to_time_t()和from_time_t().允许我们在timepoint和 “C的系统时间类型” time_t之间转换, 这意味着你可转换至/自日历时间
  • 2 steady_clock
    • 它保证绝不会被调整。 “因此当实际时间流逝, 其timepoint值绝不会 减少, 而且这些timepoint相对于真实时间都有稳定的前进速率。
  • 3 high_resolution_clock
    • 它表现的是当前系统中带有最短tick周期的clock.
      注意, 标准库井不强制规定上述clock的精准度 epoch “最小和最大timepoint的范围

2.2 Timepoint

image-20221101213432708

搭配clock,你将可以处理timepoint。

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

前面提到,

timepoint(时间点) = epoch(起始点) + duration(时间段)

以及表格提到,

timepoint t ;//根据当前的epoch建立一个timepoint
t+= d; //加上一个时间段就可以得到一个新的 timepoint

这里

#include<iostream>
#include<chrono>
using namespace std;

int main()
{
    
    

    //测试1
    // 用system_clock作为时钟,seconds作为单位 创建对象tp 初始化 2 秒
    chrono::time_point<std::chrono::system_clock,chrono::seconds>  tp(chrono::seconds(2));
    // 打印 tp距离起点的 duration (seconds)的个数
    cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
    //to epoch : 2s

    //测试2
     // 用system_clock作为时钟,seconds作为单位 创建对象tp 初始化 1分钟
    chrono::time_point<std::chrono::system_clock,chrono::seconds>  tp1(chrono::minutes(1));
    // 打印 tp距离起点的 duration (seconds)的个数
    cout << "to epoch : " <<tp1.time_since_epoch().count() << "s" <<endl;
   	//to epoch : 60s
    system("pause");
    return 0;
}
to epoch : 2s
to epoch : 60s

3.小结

这里用程序验证的不多,大部分都是一些概念 用来了解chrono库。

后续熟悉的话可能会多验证一下。

参考:C++标准库(第二版)

参考:http://t.csdn.cn/y9wUY

猜你喜欢

转载自blog.csdn.net/m0_57168310/article/details/127966945
今日推荐