• (原创)c++11中的日期和时间库


      c++11提供了日期时间相关的库chrono,通过chrono相关的库我们可以很方便的处理日期和时间。c++11还提供了字符串的宽窄转换功能,也提供了字符串和数字的相互转换的库。有了这些库提供的便利的工具类,我们能方便的处理日期和时间相关的转换和格式输出。

    chrono

      chrono库主要包含了三种类型:时间间隔Duration、时钟Clocks和时间点Time point。

    Duration

      duration表示一段时间间隔,用来记录时间长度,可以表示几秒钟、几分钟或者几个小时的时间间隔,duration的原型是:

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

      第一个模板参数Rep是一个数值类型,表示时钟个数;第二个模板参数是一个默认模板参数std::ratio,它的原型是:

    template<std::intmax_t Num, std::intmax_t Denom = 1> class ratio;

      它表示每个时钟周期的秒数,其中第一个模板参数Num代表分子,Denom代表分母,分母默认为1,ratio代表的是一个分子除以分母的分数值,比如ratio<2>代表一个时钟周期是两秒,ratio<60>代表了一分钟,ratio<60*60>代表一个小时,ratio<60*60*24>代表一天。而ratio<1, 1000>代表的则是1/1000秒即一毫秒,ratio<1, 1000000>代表一微秒,ratio<1, 1000000000>代表一纳秒。标准库为了方便使用,就定义了一些常用的时间间隔,如时、分、秒、毫秒、微秒和纳秒,在chrono命名空间下,它们的定义如下:

    typedef duration <Rep, ratio<3600,1>> hours;
    typedef duration <Rep, ratio<60,1>> minutes;
    typedef duration <Rep, ratio<1,1>> seconds;
    typedef duration <Rep, ratio<1,1000>> milliseconds;
    typedef duration <Rep, ratio<1,1000000>> microseconds;
    typedef duration <Rep, ratio<1,1000000000>> nanoseconds;

      通过定义这些常用的时间间隔类型,我们能方便的使用它们,比如线程的休眠:

    std::this_thread::sleep_for(std::chrono::seconds(3)); //休眠三秒
    std::this_thread::sleep_for(std::chrono:: milliseconds (100)); //休眠100毫秒

      chrono还提供了获取时间间隔的时钟周期个数的方法count(),它的基本用法:

    #include <chrono>
    #include <iostream>
    int main()
    {
        std::chrono::milliseconds ms{3}; // 3 毫秒
        // 6000 microseconds constructed from 3 milliseconds
        std::chrono::microseconds us = 2*ms; //6000微秒
        // 30Hz clock using fractional ticks
        std::chrono::duration<double, std::ratio<1, 30>> hz30(3.5);
        std::cout <<  "3 ms duration has " << ms.count() << " ticks
    "<<  "6000 us duration has " << us.count() << " ticks
    "
    }
    输出:
    3 ms duration has 3 ticks
    6000 us duration has 6000 ticks

             时间间隔之间可以做运算,比如下面的例子中计算两端时间间隔的差值:

    std::chrono::minutes t1( 10 );
    std::chrono::seconds t2( 60 );
    std::chrono::seconds t3 = t1 - t2;
    std::cout << t3.count() << " second" << std::endl;

             其中,t1 是代表 10 分钟、 t2 是代表 60 秒,t3 则是 t1 減去 t2,也就是 600 - 60 = 540 秒。通过t1-t2的count输出差值为540个时钟周期即540秒(因为每个时钟周期为一秒)。我们还可以通过duration_cast<>()来将当前的时钟周期转换为其它的时钟周期,比如我可以把秒的时钟周期转换为分钟的时钟周期,然后通过count来获取转换后的分钟时间间隔:

    cout << chrono::duration_cast<chrono::minutes>( t3 ).count() <<” minutes”<< endl;
    将会输出:
    9 minutes

    Time point

      time_point表示一个时间点,用来获取1970.1.1以来的秒数和当前的时间, 可以做一些时间的比较和算术运算,可以和ctime库结合起来显示时间。time_point必须要clock来计时,time_point有一个函数time_since_epoch()用来获得1970年1月1日到time_point时间经过的duration。下面的例子计算当前时间距离1970年1月一日有多少天:

    #include <iostream>
    #include <ratio>
    #include <chrono>
    
    int main ()
    {
      using namespace std::chrono;
      typedef duration<int,std::ratio<60*60*24>> days_type;
      time_point<system_clock,days_type> today = time_point_cast<days_type>(system_clock::now());
      std::cout << today.time_since_epoch().count() << " days since epoch" << std::endl;
      return 0;
    }

      time_point还支持一些算术元算,比如两个time_point的差值时钟周期数,还可以和duration相加减。下面的例子输出前一天和后一天的日期:

    #include <iostream>
    #include <iomanip>
    #include <ctime>
    #include <chrono>
    
    int main()
    {
        using namespace std::chrono;
        system_clock::time_point now = system_clock::now();
        std::time_t last = system_clock::to_time_t(now - std::chrono::hours(24));
      std::time_t next= system_clock::to_time_t(now - std::chrono::hours(24));
        std::cout << "One day ago, the time was "<< std::put_time(std::localtime(&last), "%F %T") << '
    ';
      std::cout << "Next day, the time was "<< std::put_time(std::localtime(&next), "%F %T") << '
    ';
    }

    输出:

    One day ago, the time was 2014-3-2622:38:27
    Next day, the time was 2014-3-2822:38:27

    Clocks

      表示当前的系统时钟,内部有time_point, duration, Rep, Period等信息,它主要用来获取当前时间,以及实现time_t和time_point的相互转换。Clocks包含三种时钟:

    • system_clock:从系统获取的时钟;
    • steady_clock:不能被修改的时钟;
    • high_resolution_clock:高精度时钟,实际上是system_clock或者steady_clock的别名。

    可以通过now()来获取当前时间点:

    #include <iostream>
    #include <chrono>
    
    int main()
    {
    std::chrono::steady_clock::time_point t1 = std::chrono::system_clock::now();
    std::cout << "Hello World
    ";
    std::chrono::steady_clock::time_point t2 = std::chrono:: system_clock::now();
    std::cout << (t2-t1).count()<<” tick count”<<endl;
    }

    输出:

    Hello World
    20801tick count

             通过时钟获取两个时间点之相差多少个时钟周期,我们可以通过duration_cast将其转换为其它时钟周期的duration:

    cout << std::chrono::duration_cast<std::chrono::microseconds>( t2-t1 ).count() <<” microseconds”<< endl;
    输出:
    20 microseconds

             system_clock的to_time_t方法可以将一个time_point转换为ctime:

    std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);

    而from_time_t方法则是相反的,它将ctime转换为time_point。

      steady_clock可以获取稳定可靠的时间间隔,后一次调用now()的值和前一次的差值是不因为修改了系统时间而改变,它保证了稳定的时间间隔。它的用法和system用法一样。

    时间的格式化输出

      system_clock和std::put_time配合起来使用可以格式化日期的输出,std::put_time能将日期格式化输出。下面的例子是将当前时间格式化输出:

    #include <chrono>
    #include <ctime>
    #include <iomanip>
    #include <string>
    using namespace std;
    
    int main()
    {
        auto t = chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    cout<< std::put_time(std::localtime(&t), "%Y-%m-%d %X")<<endl;
    cout<< std::put_time(std::localtime(&t), "%Y-%m-%d %H.%M.%S")<<endl;
    
        return 0;
    }

    上面的例子将输出:

    2014-3-27 22:11:49
    2014-3-27 22.11.49

    timer

      可以利用high_resolution_clock来实现一个类似于boost.timer的定时器,这样的timer在测试性能时会经常用到,经常用它来测试函数耗时,它的基本用法是这样的:

    void fun()
    {
        cout<<”hello word”<<endl;
    }
    
    int main()
    {
             timer t; //开始计时
             fun()
             cout<<t.elapsed()<<endl; //打印fun函数耗时多少毫秒
    }

      c++11中增加了chrono库,现在用来实现一个定时器是很简单的事情,还可以移除对boost的依赖。它的实现比较简单,下面是具体实现:

    #include<chrono>
    usingnamespace std;
    usingnamespace std::chrono;
    
    classTimer
    {
    public:
        Timer() : m_begin(high_resolution_clock::now()) {}
        void reset() { m_begin = high_resolution_clock::now(); }
    

    //默认输出秒
      double elapsed() const
      {
        return duration_cast<duration<double>>(high_resolution_clock::now() - m_begin).count();
      }

    //默认输出毫秒
        //int64_t elapsed() const
        //{
            //return duration_cast<chrono::milliseconds>(high_resolution_clock::now() - m_begin).count();
        //}
    
        //微秒
        int64_t elapsed_micro() const
        {
            return duration_cast<chrono::microseconds>(high_resolution_clock::now() - m_begin).count();
        }
    
        //纳秒
        int64_t elapsed_nano() const
        {
            return duration_cast<chrono::nanoseconds>(high_resolution_clock::now() - m_begin).count();
        }
    
        //
        int64_t elapsed_seconds() const
        {
            return duration_cast<chrono::seconds>(high_resolution_clock::now() - m_begin).count();
        }
    
        //
        int64_t elapsed_minutes() const
        {
            return duration_cast<chrono::minutes>(high_resolution_clock::now() - m_begin).count();
        }
    
        //
        int64_t elapsed_hours() const
        {
            return duration_cast<chrono::hours>(high_resolution_clock::now() - m_begin).count();
        }
    
    private:
        time_point<high_resolution_clock> m_begin;
    };

    测试代码:

    void fun()
    {
        cout<<”hello word”<<endl;
    }
    
    int main()
    {
             timer t; //开始计时
             fun()
             cout<<t.elapsed()<<endl; //打印fun函数耗时多少毫秒
    cout<<t.elapsed_micro ()<<endl; //打印微秒
    cout<<t.elapsed_nano ()<<endl; //打印纳秒
    cout<<t.elapsed_seconds()<<endl; //打印秒
    cout<<t.elapsed_minutes()<<endl; //打印分钟
    cout<<t.elapsed_hours()<<endl; //打印小时
    }

    如果你觉得这篇文章对你有用,可以点一下推荐,谢谢。

    c++11 boost技术交流群:296561497,欢迎大家来交流技术。

  • 相关阅读:
    20200226 Java IO流——廖雪峰
    20200225 Java 多线程(2)-廖雪峰
    20200225 Java 多线程(1)-廖雪峰
    20200224 尚硅谷ElasticSearch【归档】
    20200224 一 概述
    20200222 尚硅谷Dubbo【归档】
    20200222 四、dubbo原理
    Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
    Reinforcement learning in populations of spiking neurons
    Solving the Distal Reward Problem through Linkage of STDP and Dopamine Signaling
  • 原文地址:https://www.cnblogs.com/qicosmos/p/3642712.html
Copyright © 2020-2023  润新知