C++11 处理时间和日期的处理,以及chrono库介绍

C++11提供了日期和时间相关的库chrono,通过这个库可以很方便的对时间和日期进行处理:
chrono库主要包含三种类型:

1.时间间隔duration

介绍一下duraton的原型:

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

Rep表示时钟数的类型,Period表示时钟周期。

C++标准库中的一些时间间隔:

typedf duration<Rep, ratio<3600, 1>> hours;
typedf duration<Rep, ratio<60, 1>> minutes;
typedf duration<Rep, ratio<3600, 1>> seconds;
typedf duration<Rep, ratio<1, 1000>> milliseconds; 

同时,还提供了获取时钟周期数的方法count().

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <random>
#include <chrono>

int main()
{
    std::chrono::milliseconds ms(3);    // 3ms
    std::chrono::microseconds micro_s = 2 * ms;
    std::cout << "milliseconds count is " << ms.count() << std::endl;
    std::cout << "microseconds count is " << micro_s.count() << std::endl;

    std::chrono::duration<double, std::ratio<1, 30>> hz30(3.5);   // 30hz time clock

    // 时间相减
    std::chrono::minutes t1(10);
    std::chrono::seconds t2(64);
    std::chrono::seconds t3 = t1 - t2;
    std::cout << "t3 count is " << t3.count() << std::endl;
    std::cout << typeid(t3).name() << std::endl;   // 查看变量的类型

    // 对时钟周期的转换
    std::chrono::minutes h1 = std::chrono::duration_cast<std::chrono::minutes>(t3);    // 这个转换只能转换为整数
    std::cout << "The minute is " << h1.count() << std::endl;
    return 0;
}

运行结果如下所示:
C++11  处理时间和日期的处理,以及chrono库介绍

2.时钟clock

clocks表示当前的系统时钟。clock包含三种时钟:
1. system_clock: 代表真实世界的挂钟时间,具体指依赖于系统。保证提供的时间值是一个可读的时间。

2. steady_clock: 不能被调整的时钟,保证先后得到的时间是递增的。

3. high_resulution_clock: 高精度时钟。

例如:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <random>
#include <chrono>
#include <ctime>
#include <string>

int main()
{
    std::chrono::system_clock::time_point t1 = std::chrono::system_clock::now();  // 获取时间
    for (int i = 0; i < 10000; i++)
    {

    }
    std::chrono::system_clock::time_point t2 = std::chrono::system_clock::now();
    // 两个时间点之间相差的时钟周期
    std::cout << "Time elapsed " << (t2 - t1).count() << std::endl;
    // 将时间进行转换
    int mico_s = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
    std::cout << "Time is " << mico_s << " microseconds" << std::endl;

    // time_point(chrono库)和c_time(ctime库)之间的转换
    // 函数to_time_t 和 from_time_t
    std::time_t t3 = clock();
    for (int i = 0; i < 1000; i++)
    {
        for (int j = 0; j < 1000; j++)
        {

        }
    }
    std::time_t elapsed = clock() - t3;
    std::cout << "t3 is " << elapsed << std::endl;

    std::time_t t_time =  std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(elapsed);

    return 0;
}

3. 时间点time_point

time_point表示时间点,用来获取从纪元开始所经过的duration和当前时间,可以做一些时间的比较和算术运算。

#include "stdafx.h"
#include <iostream>
#include <random>
#include <chrono>

int main()
{
    // 计算从1970-1-1至今经过的天数
    typedef std::chrono::duration<int, std::ratio<60 * 60 * 24, 1>> day_type;   // 定义一天的duration
    std::chrono::time_point<std::chrono::system_clock, day_type> today =
        std::chrono::time_point_cast<day_type>(std::chrono::system_clock::now());
    std::cout << "Elapse days count is " << today.time_since_epoch().count() << std::endl;
    return 0;
}

两个time_point支持相加减操作。但是不同clock的time_point是不能相加减的。

#include "stdafx.h"
#include <iostream>
#include <random>
#include <chrono>
#include <ctime>
#include <string>
// 由于没有找到put_time函数,所以自定义一个时间转换的函数

int main()
{
    using namespace std::chrono;

    system_clock::time_point now = system_clock::now();
    std::time_t last = system_clock::to_time_t(now - hours(24));     // 向time_T转换
    std::time_t next = system_clock::to_time_t(now + hours(24));
    std::cout << "one day ago the time was " << std::localtime(&last)->tm_mon << std::endl;
    // std::localtime(&last)返回的是一个结构体指针,该结构体中包含具体的时间信息,std::put_time不可用的话需要自己将时间拼接成需要的格式
    return 0;
}

计时器Timer

利用high_resolution_clock可以实现一个计时器,这样的timer在测试程序性能时经常用到,计时器的实现代码如下所示:

#pragma once
#include <chrono>

using namespace std;

// 定义Timer类
class Timer
{
private:
    chrono::time_point<chrono::high_resolution_clock> begin;

public:
    Timer() : begin(chrono::high_resolution_clock::now()) {}   // 构造函数

    // reset方法
    void reset()
    {
        begin = chrono::high_resolution_clock::now();
    }

    // 输出经过的时间,定义为模板函数
    template<typename Duration=chrono::milliseconds>   // 默认输出毫秒ms
    int64_t elapsed() const
    {
        return chrono::duration_cast<Duration>(chrono::high_resolution_clock::now() - begin).count();
    }

    // 输出微妙
    int64_t elapsed_microseconds()
    {
        return elapsed<chrono::milliseconds>();
    }

    // 输出纳秒
    int64_t elapsed_nanoseconds()
    {
        return elapsed<chrono::nanoseconds>();
    }

    // 输出秒
    int64_t elapsed_seconds()
    {
        return elapsed<chrono::seconds>();
    }

    // 输出分minute
    int64_t elapsed_minutes()
    {
        return elapsed<chrono::minutes>();
    }

    // 输出时hour
    int64_t elapsed_hours()
    {
        return elapsed<chrono::hours>();
    }
};

Timer的基本用法:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include "stdafx.h"
#include "Timer.h"

int main()
{
    Timer timer;  // 开始计时
    for (int i = 0; i < 10000; i++)
    {
        for (int j = 0; j < 10000; j++) {}
    }
    std::cout << "Elapsed " << timer.elapsed() << " ms" << std::endl;
    std::cout << "Elapsed " << timer.elapsed_seconds() << " s" << std::endl;
    std::cout << "Elapsed " << timer.elapsed_nanoseconds() << " ns" << std::endl;
    return 0;
}

输出结果:

C++11  处理时间和日期的处理,以及chrono库介绍

---------------------------------------------------------------------------------------------------------------------------

ctime库中测量时间的方法:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include "Timer.h"

const double CLOCK_PER_SECOND = static_cast<double>(CLOCKS_PER_SEC);  // 每秒钟的时钟数
const double CLOCK_PER_MILLISEC = CLOCK_PER_SECOND / 1000.0;          // 每毫秒的时钟数   

int main()
{
   std::time_t start = clock();
   for (int i = 0; i < 10000; i++)
   {
       for (int j = 0; j < 10000; j++) {}
   }
   double elapsed_ms = (clock() - start) / CLOCK_PER_MILLISEC;
   std::cout << "Timer elapsed " << elapsed_ms << " ms" << std::endl;
   return 0;
}

将ctime中的测量时间的方法也可以封装为一个计时器Timer。

 

原文链接: https://www.cnblogs.com/ncepubye/p/12724021.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++11  处理时间和日期的处理,以及chrono库介绍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/396523

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月6日 上午11:22
下一篇 2023年4月6日 上午11:22

相关推荐