chrono库的使用

数据类型

duration

  1.类的声明及实例:

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

  duration类是一个模板类,使用一个计数器和比例来表示一个时间跨度.其中模板参数Rep一般是算术类型或者可以用作计数的类型;Period是ratio类型,表示以秒为单位的计算比例。duration有很多类型实例,如下所示:

类型 数据范围 比例
hours 至少23bits的有符号整数类型 ratio<3600,1>
minutes 至少29bits的有符号整数类型 ratio<60,1>
seconds 至少35bits的有符号整数类型 ratio<1,1>
milliseconds 至少45bits的有符号整数类型 ratio<1,1000>
microseconds 至少55bits的有符号整数类型 ratio<1,1000000>
nanoseconds 至少64bits的有符号整数类型 ratio<1,1000000000>

  2.类的成员函数
  (1)count:返回duration对象所表示的时间跨度的计数器,单位基于该对象的类型。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main(){
    using namespace chrono;
    // count 函数的使用示例
    hours h(1);
    minutes m(60);
    cout<<"h.count() = "<<h.count()<<endl;
    cout<<"m.count() = "<<m.count()<<endl;

    return 0;
}

  运行结果如下所示:

h.count() = 1
m.count() = 60

  (2)zero:返回一个duration类的0值,因为duration类的计数表示为模板,使用该类专用的0值比较更加安全。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main(){
    using namespace chrono;
    steady_clock::time_point t1 = steady_clock::now();
    steady_clock::time_point t2 = steady_clock::now();
    steady_clock::duration d = t2 - t1;
    if( d == steady_clock::duration::zero() )
        cout << "d is zero" << endl;
    else
        cout << "d is not zero" << endl;
    return 0;
}

  运行结果如下所示:

d is zero

  (3)minmax:返回duration类型的最大和最小值。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
  std::cout << "system_clock durations can represent:\n";
  std::cout << "min: " << std::chrono::system_clock::duration::min().count() << "\n";
  std::cout << "max: " << std::chrono::system_clock::duration::max().count() << "\n";
  return 0;
}

  运行结果如下所示:

min: -9223372036854775808
max: 9223372036854775807

time_point

  1.类的声明

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

  time_point也是一个模板类,一个time_point类表示相对于时钟纪元的时间点。其中模板参数Clock表示一个clock类,比如system_clock,steady_clock,high_resolution_clock或者自定义的clock类,用于表示使用的时钟类型;模板参数Duration默认是一个duration类,用于表示一个时间点。
  2.成员函数
  (1)time_since_epoch:返回一个duration对象,其时间跨度值介于纪元和当前时间点之间。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
  using namespace std::chrono;
  system_clock::time_point tp = system_clock::now();
  system_clock::duration dtn = tp.time_since_epoch();
  std::cout << "current time since epoch, expressed in:" << std::endl;
  //当前duration类的计数器数值,默认是以纳秒为单位
  std::cout << "periods: " << dtn.count() << std::endl;
  //当前duration类的计数器数值转换成秒,使用period类的num和den(即比例)
  std::cout << "seconds: " << dtn.count() * system_clock::period::num / system_clock::period::den;
  std::cout << std::endl;
  return 0;
}

  运行结果如下所示:

periods: 1669885492176385200
seconds: 1669885492

  (2)minmax:返回一个time_point类能表示的最小和最大值。具体实现其实返回的就是duration的最小最大值。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
  std::cout << "system_clock time_point can represent:\n";
  std::cout << "min: " << std::chrono::system_clock::time_point::min().time_since_epoch().count() << "\n";
  std::cout << "max: " << std::chrono::system_clock::time_point::max().time_since_epoch().count() << "\n";
  return 0;
}

  运行结果如下所示:

min: -9223372036854775808
max: 9223372036854775807

时钟类型

  chrono库中的时钟类型有三种,分别是system_clock、steady_clock和high_resolution_clock。

system_clock

性质

  system_clock提供对当前time_point的访问。具体来说,system_clock是一个系统范围内的实时时钟。
  (1)实时性
  system_clock的实时时间可以和其他形式的时间表示进行数据转换(使用to_time_t和from_time_t)。
  (2)有符号性
  system_clock的实时时间可以使用负数表示纪元前的时间。
  (3)系统性
  系统上所有运行的进程都可以通过system_clock来获取相同的实时时间。

成员函数

  (1)now:返回system_clock的当前时间。
  (2)to_time_t:将time_point类型转换为time_t类型。
  (3)from_time_t:将time_t类型转换为time_point类型。
  示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    hours one_day(24);
    //获取当前时间并计算明天的时间
    system_clock::time_point tp = system_clock::now();
    system_clock::time_point tomorrow = tp + one_day;
    time_t tt;
    tt = system_clock::to_time_t(tp);
    cout << "today is: " << ctime(&tt);
    tt = system_clock::to_time_t(tomorrow);
    cout << "tomorrow will be: " << ctime(&tt);
    tt = 822326400;         // 1996-01-23 00:00:00
    system_clock::time_point birthday = system_clock::from_time_t(tt);
    cout << "my birthday is: " << ctime(&tt);
    return 0;
}

  运行结果如下所示:

today is: Wed Nov 30 14:45:11 2022
tomorrow will be: Thurs Dec 01 14:45:11 2022
my birthday is: Tue Jan 23 00:00:00 1996

steady_clock

性质

  steady_clock提供对当前time_point的访问。steady_clock专门用于计算时间间隔。
  (1)单调性
  steady_clock的实时时间是单调递增的,其now成员函数返回的时间一定不会比前一次的调用早。
  (2)稳定性
  steady_clock时钟前进的每一秒都需要相同的时间。

成员函数

  (1)now:返回system_clock的当前时间。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    steady_clock::time_point start = steady_clock::now();
    // do something
    for(int i = 0; i < 100000000; i++){
        i+=1; i-=1;
    }
    steady_clock::time_point end = steady_clock::now();
    milliseconds time_span = duration_cast<milliseconds>(end - start);
    cout << "It took me " << time_span.count() << " milliseconds.";
    return 0;
}

  运行结果如下所示:

It took me 77 milliseconds.

high_resolution_clock

性质

  high_resolution_clock提供对当前time_point的访问。high_resolution_clock具有最短时钟周期的时钟,因此是高精度的时钟,具体实现可能是system_clock或者stale_clock。
  (1)单调性
  steady_clock的实时时间是单调递增的,其now成员函数返回的时间一定不会比前一次的调用早。
  (2)稳定性
  steady_clock时钟前进的每一秒都需要相同的时间。

成员函数

  (1)now:返回system_clock的当前时间。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    steady_clock::time_point start = steady_clock::now();
    // do something
    for(int i = 0; i < 100000000; i++){
        i+=1; i-=1;
    }
    steady_clock::time_point end = steady_clock::now();
    milliseconds time_span = duration_cast<milliseconds>(end - start);
    cout << "It took me " << time_span.count() << " milliseconds.";
    return 0;
}

  运行结果如下所示:

It took me 77 milliseconds.

三种时钟的对比

  一般情况下,system_clock和high_resolution_clock的now函数获取的时钟是相同的,steady_clock获取的时钟一般是系统运行的时间,也就是计算机开机之后持续的时间。以下是使用三种时钟分别获取当前时间的结果(单位为毫秒)。

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    time_t system_clock_timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    time_t steady_clock_timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
    time_t high_resolution_clock_timestamp = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
    cout << "system_clock_timestamp: " << system_clock_timestamp << endl;
    cout << "steady_clock_timestamp: " << steady_clock_timestamp << endl;       //系统的开机时间
    cout << "high_resolution_clock_timestamp: " << high_resolution_clock_timestamp << endl;
    return 0;
}

  运行结果如下所示:

system_clock_timestamp: 1669967114590
steady_clock_timestamp: 443450655
high_resolution_clock_timestamp: 1669967114590

转换函数

duration_cast

  duration_cast是duration类的显式转换函数,能将不同的duration类进行转换,比如将hours类转换为minutes类。这种转换必须使用显示转换,其工作原理是将内部的计数器类型转换为common_type,然后再根据目标的单位计算比例进行转换,内部使用的转换是static_cast。另外,如果遇到目标类型的精度较低,那么该值将会被截断。
  转换的示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    hours one_hour(1);
    minutes one_hour_in_minutes = duration_cast<minutes>(one_hour);
    seconds one_hour_in_seconds = duration_cast<seconds>(one_hour);
    milliseconds one_hour_in_milliseconds = duration_cast<milliseconds>(one_hour);
    microseconds one_hour_in_microseconds = duration_cast<microseconds>(one_hour);
    nanoseconds one_hour_in_nanoseconds = duration_cast<nanoseconds>(one_hour);
    cout << "one_hour_in_minutes = " << one_hour_in_minutes.count() << endl;
    cout << "one_hour_in_seconds = " << one_hour_in_seconds.count() << endl;
    cout << "one_hour_in_milliseconds = " << one_hour_in_milliseconds.count() << endl;
    cout << "one_hour_in_microseconds = " << one_hour_in_microseconds.count() << endl;
    cout << "one_hour_in_nanoseconds = " << one_hour_in_nanoseconds.count() << endl;
    return 0;
}

  运行结果如下所示:

one_hour_in_minutes = 60
one_hour_in_seconds = 3600
one_hour_in_milliseconds = 3600000
one_hour_in_microseconds = 3600000000
one_hour_in_nanoseconds = 3600000000000

time_point_cast

  time_point_cast用来转换基于不同duration的time_point类,转换过程中能够正确的考虑其进率的不同。比如,now函数返回的time_point转换成自定义换算进率的time_point类型。示例如下所示:

#include<bits/stdc++.h>
using namespace std;
int main (){
    using namespace chrono;
    // 1 day = 86400 seconds
    using daysType = duration<int, ratio<60*60*24>>;
    // 获取当前时间,并转换成天数    
    time_point<system_clock,daysType> today = time_point_cast<daysType>(system_clock::now());
    // 输出转换后的天数
    cout << "Today is " << today.time_since_epoch().count() << " days since epoch" << endl;
    return 0;
}

  运行结果如下所示:

Today is 19326 days since epoch

当珍惜每一片时光~