c11 chrono详解

转自:https://blog.csdn.net/hou8389846/article/details/77962343#commentBox

chrono是c++11的时间库,提供计时,时钟等功能。
了解chrono,主要了解时间段(duration)和时间点(time_point)的概念。

1、精度(ratio)

时钟节拍(时间精度):

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

其中N表示分子(对应period::num),D表示分母(默认用秒表示的时间单位,对应period::den)。
常用的单位:

ratio<3600, 1> hours;
ratio<60, 1> minutes;
ratio<1, 1> seconds;
ration<1, 1000> milliseconds;

test:

#include 
#include 
using namespace std;
int main(int argc, char *argv[])
{
    cout << "milliseconds = ";
    cout << std::chrono::milliseconds::period::num << "/" \
         << std::chrono::milliseconds::period::den << "s" << endl; //out: 1/1000s

    typedef std::chrono::duration<int, std::ratio<1, 2> > halfseconds;

    cout << "halfseconds = ";
    cout << halfseconds::period::num << "/" \
         << halfseconds::period::den << "s" << endl; //out: 1/2s

    cout << "microseconds = ";
    cout << std::chrono::microseconds::period::num << "/" \
         << std::chrono::microseconds::period::den << "s" << endl; //out: 1/1000000s
    return 0;
 }

2、时间段(duration)

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

std::chrono::duration(时间段)表示一段时间,如半个小时,12.88秒,半天,一炷香的时间等等。

Rep表示一种数值类型,用来表示Period数量。如:int,float, double;
Period是ratio类型,用来表示时间精度。如:hours,seconds,minutes等;

chrono中宏定义了很多特例化的duration:

typedef std::chrono::duration<int64_t> seconds;
typedef std::chrono::duration<int64_t, ratio<60> >	munites;
typedef std::chrono::duration<int64_t, ratio<3600> > hours;
typedef std::chrono::duration<int64_t, ratio<1, 1000> >	milliseconds;

构造函数

duration() = default;

duration(const duration& dtn);

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

template<class Rep>
constexpr duration(const Rep & rep);

成员函数count()显示单位时间的数量

example:

#include 
#include 
using namespace std;

int main(int argc, char *argv[])
{

    cout << "microseconds = ";
    cout << std::chrono::microseconds::period::num << "/" \
         << std::chrono::microseconds::period::den << "s" << endl;

    typedef std::chrono::duration<int64_t, ratio<1, 2> > halfseconds;

    halfseconds halfsec(1000);
    cout << halfsec.count() << endl; //out: 1000
    cout << "halfsec(1000) = " << halfsec.count()*halfseconds::period::num/ \
            halfseconds::period::den << "s" << endl; //out: 500s

    std::chrono::milliseconds ms(2000);
    cout << ms.count() << endl; //out: 2000
    cout << "milliseconds(2000) = " << halfsec.count()* \
            std::chrono::milliseconds::period::num/ \
            std::chrono::milliseconds::period::den << "s" << endl; //out: 1s

    return 0;
}

时间段的显示转换由std::chrono::duration_cast<> 来实现。

std::chrono::milliseconds ms(54800);
std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(ms);//out:sec = 54S

3、时间点(time_point)

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

std::chrono::time_point表示一个具体时间(能用计算机时间表示),如:今天下午3点,火车出发时间等等。
模板第一个参数Clock指定所有的时钟(标准库中有三种时钟:system_clock、steady_clock和high_resulotion_clock),第二个参数表示时间的计量单位(特化std::chrono::duration<>)。
时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。

构造函数

time_point() = default;//默认构造函数

template<class Duration2>
time_point(const time_point<clock, Duration2> &tp); //拷贝构造函数

explicit time_point(const duration &dtn);//用duration来构造,就是距离时间戳的长度

duration time_since_epoch()

此函数表示当前时间距离时间戳的时间长度,即当前时间点到时间戳(1970年1月1日 00:00)的时间距离,返回duration的精度与构造time_point的Clock有关。
test

#include 
#include 
#include 
using namespace std;

int main(int argc, char *argv[])
{
    using namespace std::chrono;
    time_point<system_clock, seconds> tp(seconds(2));
    cout << "time_since_epoch = " << tp.time_since_epoch().count() << endl;

    //转换成ctime,打印时间点
    time_t tt = system_clock::to_time_t(tp);
    char a[50] = {0};
    ctime_s(a, 50, &tt);
    cout << a << endl;//out:Thu Jan 01 08:00:02 1970
    
    return 0;
}

4、时钟(当前系统时间)

chrono中包含三种系统时钟:system_clock、steady_clock、high_resolution_clock。每一个clock类都有确定的time_point、duration、Rep和Period类型。
system_clock是不稳定的。因为时钟是可调的,即这种是完全自动适应本地账户的调节。这种调节可能造成的是,首次调用now()返回的时间要早于上次调用now()所返回的时间,这就违反了节拍频率的均匀分布。稳定闹钟对于超时的计算很重要,所以C++标准库提供一个稳定时钟 std::chrono::steady_clock。std::chrono::high_resolution_clock 是标准库中提供的具有最小节拍周期(因此具有最高的精度的时钟)。
time_since_epoch()和now()的返回值都依赖于时钟的精度。检测精度的方法:

#include 
#include 
using namespace std;

int main(int argc, char *argv[])
{
    using namespace std::chrono;
    cout << "system clock:  " \
         << system_clock::period::num << "/" << \
            system_clock::period::den << "s" << endl; //out:1/1000000000(1ns)

    cout << "steady clock:  " \
         << steady_clock::period::num << "/" << \
            steady_clock::period::den << "s" << endl; //out:1/1000000000(1ns)

    cout << "high resolution clock:  " \
         << high_resolution_clock::period::num << "/" << \
            high_resolution_clock::period::den << "s" << endl; //out:1/1000000000(1ns)

    return 0;
}

成员函数

 //获取当前系统时间
static time_point now() noexcept;

//time_point的转换函数
template<class ToDuration, class Clock, class Duration>
time_point<Clock, ToDuration> time_point_cast(const time_point<Clock,Duration> &tp);

//time_point转换成ctime(秒)
to_time_t()

//ctime转换成time_point
from_time_t()

综合应用

输出当前时间,并且计算当前的时间距离1970年1月1日00:00的毫秒数,计算两个时间的时间长度。

#include 
#include 
#include 
using namespace std;

int main(int argc, char *argv[])
{
    using namespace std::chrono;

    //显示当前系统时间及距离时间戳的时间长度(秒)
    typedef chrono::time_point<chrono::system_clock, chrono::seconds> secClock;
    secClock sec = chrono::time_point_cast<chrono::seconds>(chrono::system_clock::now());

    time_t tt =  system_clock::to_time_t(sec);

    char a[50];
    ctime_s(a, sizeof (a), &tt);
    cout << "time now[s] : " << a;

    cout << "to 1970-1-1,00:00[s]  " << sec.time_since_epoch().count() << "s" << endl;

    for(unsigned int i = 0; i < 1000000000; ++i) {
        if(i%10000000 == 0) {
            cout << "*";
        }
    }
    cout << endl;

    //显示当前系统时间及距离时间戳的时间长度(毫秒)
    typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> milliClock;
    milliClock ms = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());

    time_t mt = chrono::system_clock::to_time_t(ms);

    char cmt[50] = {0};
    ctime_s(cmt, sizeof (cmt), &mt);
    cout << "now time[ms] = " << cmt;

    cout << "to 1970-1-1,00:00[ms]  " << ms.time_since_epoch().count() << "ms" << endl;


    //计算两个时间的时间长度[秒级]
    cout << "from sec to ms :" << (chrono::time_point_cast<chrono::seconds>(ms) - sec).count() << endl;

    return 0;
}

你可能感兴趣的:(c++)