std::chrono time

Header file: #include <chrono>

The time library chrono of c++11 is located under the namespace std::chrono.

Namespace: using namespace std::chrono;

Macro definition:

#define _XTIME_NSECS_PER_TICK 100
#define _XTIME_TICKS_PER_TIME_T (long long)10000000

clock

 The c++11 time library chrono simplifies the programming and development of the calculation of time, date, and time interval; mainly reflected in:

    1. Obtain the exact time point (time_point) of the clock (clock) based on system_clock, steady_clock, and high_resolution_clock;

    2. Calculation of the time interval (duration) based on the difference between different time units and different time points;

The time library chrono of c++11 is located under the namespace std::chrono.

 1. Clock:

    包括system_clock、steady_clock、high_resolution_clock;

    1. system_clock: The real-time clock provided by the system, the time obtained by all processes using the now() method is the same;

    2. Steady_clock: a monotonic clock that will not be adjusted, ensuring that even if the system is modified while the process is running, and the now() method is called again, the current time based on the previous system time can still be obtained;

    3. high_resolution_clock: is the typedef of system_clock and steady_clock

chrono::system_clock::now()
For system_clock, its starting point is epoch, which is 1970-01-01 00:00:00 UTC, and its scale is 1 tick, which is _XTIME_NSECS_PER_TICK nanoseconds.

The steady_clock clock is different from system_clock. The system_clock corresponds to the system time. If you manually adjust or the operating system automatically synchronizes with the network clock, the time obtained by calling system_clock.now() will also be affected. The second call may be Instead, the time obtained when calling is earlier. steady_clock guarantees that the time advances at a constant speed and is not affected by the adjustment of the system clock.

steady_clock::duration d = steady_clock::now().time_since_epoch(); What you get is the time interval between the current time and 1970.1.1. Through type conversion, it can be converted into various precision representations.

The accuracy of this function is 1 tick, which is 100 nanoseconds;

二、time_point:

    Based on the clock, time_point can be obtained. The so-called time point refers to a certain moment, such as 2018.4.17 17:13:15;

    time_point appears in two forms:

    1. Time_point under the namespace std::chrono:

          std::chrono::time_point is a template class, you need to specify the used clock class (system_clock/steady_clock/high_resolution_clock) and precision (the default is hour level, which can be specified by std::ratio);

//std::chrono::time_point is a template class, not used usually.
std::chrono::time_point<std::chrono::high_resolution_clock, std::chrono::duration<int, std::ratio<60 * 60 * 24>>> now_daylevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<60 * 60 * 24>>>(std::chrono::high_resolution_clock::now());
std::chrono::time_point<std::chrono::high_resolution_clock, std::chrono::duration<int, std::ratio<60 * 60>>> now_hourlevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<60 * 60>>>(std::chrono::high_resolution_clock::now());
std::chrono::time_point<std::chrono::high_resolution_clock, std::chrono::duration<int, std::ratio<60>>> now_minutelevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<60>>>(std::chrono::high_resolution_clock::now());
std::chrono::time_point<std::chrono::high_resolution_clock, std::chrono::duration<int, std::ratio<1>>> now_secondlevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<1>>>(std::chrono::high_resolution_clock::now());
std::chrono::time_point<std::chrono::high_resolution_clock> now_deflevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<60 * 60 * 24>>>(std::chrono::high_resolution_clock::now());

The current time obtained by the hour, minute, second, and default 4 methods are obtained above, and then converted to unixtime timestamp:

std::time_t ut_day = std::chrono::high_resolution_clock::to_time_t(now_daylevel);
ut_hour = std::chrono::high_resolution_clock::to_time_t(now_hourlevel);
ut_minute = std::chrono::high_resolution_clock::to_time_t(now_minutelevel);
ut_second = std::chrono::high_resolution_clock::to_time_t(now_secondlevel);
ut_def = std::chrono::high_resolution_clock::to_time_t(now_deflevel);

Then use ctime to convert to date and time format:

    std::cout << ut_day << std::endl;
    std::cout << ctime(&ut_day) << std::endl;
 
    std::cout << ut_hour << std::endl;
    std::cout << ctime(&ut_hour) << std::endl;
 
    std::cout << ut_minute << std::endl;
    std::cout << ctime(&ut_minute) << std::endl;
 
    std::cout << ut_second << std::endl;
    std::cout << ctime(&ut_second) << std::endl;
 
    std::cout << ut_def << std::endl;
    std::cout << ctime(&ut_def) << std::endl;

Observation results:

 1523923200

            Tue Apr 17 08:00:00 2018------------------day

            1523955600

            Tue Apr 17 17:00:00 2018------------------hour

            1523957460

            Tue Apr 17 17:31:00 2018------------------minute

            1523957497

            Tue Apr 17 17:31:37 2018------------------second

            1523923200

            Tue Apr 17 08:00:00 2018------------------default

   Points to be mastered:

            1. How to define a point in time

                1.1. Template class std::chrono::time_point:

                Need template instantiation: clock type (required, system_clock/steady_clock/high_resolution_clock), precision level (optional)

               如:std::chrono::time_point<std::chrono::high_resolution_clock, std::chrono::duration<int, std::ratio<60 * 60 * 24>>> now_daylevel = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<60 * 60 * 24>>>(std::chrono::high_resolution_clock::now());

                This method is more troublesome

                1.2, std::chrono::clock type::time_point

                  include:

                    std::chrono::system_clock::time_point

                    std::chrono::steady_clock::time_point

                    std::chrono::high_resolution_clock::time_point

                    如:std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();

                    This way is relatively simple

            2. Conversion from time_point to unixtime timestamp:

                Method: std::chrono::clock type::to_time_t(time_point) method

                Such as:

                std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();

                std::time_t ut_now = std::chrono::high_resolution_clock::to_time_t(now);

                You can use stl's ctime to realize the conversion of unixtime timestamp to date and time format:

                std::cout << "now: " << ctime(&ut_now);

            3. Time_since_epoch method

                Calculate how many days, hours, minutes, and seconds have passed since January 1, 1970 to the present

            4. Realize incremental time calculation through duration

                Pass a time time_point_1, add and subtract duration to get another time time_point_2

                See the introduction of duration below
 

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

auto start = system_clock::now();
// do something...
auto end   = system_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout <<  "花费了" 
     << double(duration.count()) * microseconds::period::num / microseconds::period::den   << "秒" << endl;

duration_cast<> means type conversion
microseconds means subtle. In addition, there are five time units: hours, minutes, seconds, milliseconds, nanoseconds.
num and den represent the numerator and denominator, respectively. In the code I gave, num is equal to 1, den is equal to 1,000,000
count() is used to return the time

steady_clock::duration d = steady_clock::now().time_since_epoch();
minutes min = duration_cast<minutes>(d);
seconds sec = duration_cast<seconds>(d);
milliseconds mil = duration_cast<milliseconds>(d);
microseconds mic = duration_cast<microseconds>(d);
nanoseconds nan = duration_cast<nanoseconds>(d);
cout << min.count() << "分钟" << endl;
cout << sec.count() << "秒" << endl;
cout << mil.count() << "毫秒" << endl;
cout << mic.count() << "微妙" << endl;
cout << nan.count() << "纳秒" << endl;

steady_clock

Used in scenarios where the time interval needs to be obtained, and this time interval will not be affected by modifying the system time

auto tp1 = std::chrono::steady_clock::now();
//do something
auto tp2 = std::chrono::steady_clock::now();
std::cout << std::chrono::duration_caststd::chrono::microseconds(tp2 - tp1).count() << “microseconds” << std::endl;

Get timestamp

std::time_t getTimeStamp()
{
    std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
    auto tmp=std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
    std::time_t timestamp = tmp.count();
    //std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
    return timestamp;
}

Timestamp to date

Where int64 is a custom cross-platform data type

std::tm* gettm(int64 timestamp)
{
    int64 milli = timestamp+ (int64)8*60*60*1000;//此处转化为东八区北京时间,如果是其它时区需要按需求修改
    auto mTime = std::chrono::milliseconds(milli);
    auto tp=std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>(mTime);
    auto tt = std::chrono::system_clock::to_time_t(tp);
    std::tm* now = std::gmtime(&tt);
    printf("%4d年%02d月%02d日 %02d:%02d:%02d\n",now->tm_year+1900,now->tm_mon+1,now->tm_mday,now->tm_hour,now->tm_min,now->tm_sec);
   return now;
}

Three, duration

Core points:

            1. Duration means a period of time, such as "100 milliseconds", "one second", "2 minutes", "5 hours", "10 days"...

            2. Duration is based on seconds, and each custom time unit is derived from std::ratio, including but not limited to: days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, stl provides by default: hours, minutes , Seconds, milliseconds, microseconds, nanoseconds;

            3. Duration itself can do addition and subtraction operations, such as: time period d3 = time period d1-time period d2

            4. Duration can provide duration_cast, which can be converted from one time unit to another time unit, such as 1 hour and 60 minutes can be converted to each other

            5. Time time_point can get another time by adding and subtracting duration;

            1 and 2, introduction to duration

            std::ratio represents a ratio, or ratio, it is a template class, the definition is:

template<intmax_t _Nx, intmax_t _Dx = 1>  
struct ratio  
{    // holds the ratio of _Nx to _Dx  
    static_assert(_Dx != 0, "zero denominator");  
    static_assert(-INTMAX_MAX <= _Nx, "numerator too negative");  
    static_assert(-INTMAX_MAX <= _Dx, "denominator too negative");  
      
    static constexpr intmax_t num = _Sign_of<_Nx>::value  
            * _Sign_of<_Dx>::value * _Abs<_Nx>::value / _Gcd<_Nx, _Dx>::value;  
      
    static constexpr intmax_t den = _Abs<_Dx>::value / _Gcd<_Nx, _Dx>  
            ::value;  
      
    typedef ratio<num, den> type;  
};

                PS: intmax_t is long long

                In short, _Nx = 60 and _Dx = 1, then the ratio is 60, which can be used to represent minutes:               

std::chrono::duration<int, std::ratio<60>> one_minute(1);
std::chrono::duration<int, std::ratio<60>> three_minute(3);

                i. std::chrono::duratio represents the time interval, the benchmark is 1 second;

                ii. The first parameter int of template instantiation, which represents the length of the time interval, is represented by an integer;

                iii. The second parameter of template instantiation, std::ratio<60>, represents the ratio of time interval to second is 60:1. Note that the default instantiation of ratio _Dx is 1, that is, std::ratio<60> is equivalent In std::ratio<60, 1>; the ratio of 60:1 is equivalent to std::chrono::duration<int, std::ratio<60>> is a data structure representing a one-minute time interval;

                iv. According to this data structure, the object one_minute is constructed with a construction parameter of 1, which represents the object one_minute representing a one-minute time interval; and the object three_minute is constructed with a construction parameter of 3, which represents the object three_minute representing a 3-minute time interval;

                If the principle of the minute structure is clear, then it is feasible to construct a time interval of any length of time;

                Code:   

std::chrono::duration<int, std::ratio<3>> three_second(1);
     
    std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();  std::this_thread::sleep_for(three_second);   std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
     
    std::time_t ut1 = std::chrono::high_resolution_clock::to_time_t(t1), ut2 = std::chrono::high_resolution_clock::to_time_t(t2);
    std::cout << "t1: " << ctime(&ut1);
    std::cout << "t2: " << ctime(&ut2);

                The above code means to construct a time interval of 3 seconds, three_minute, and then record the time and moment (time_point) t1 at this moment, and then put the current thread to sleep for 3 seconds, and then record the time and moment (time_point) again after the thread resumes operation. ) t2, then output t1 and t2, and observe whether the difference between t1 and t2 is 3 seconds;

                As mentioned earlier, time_point can get different moments by adding and subtracting duration:   

    std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
     
    std::chrono::duration<int, std::ratio<60>> one_minute(1);
    std::chrono::duration<int, std::ratio<60 * 60 * 24>> one_day(1);

    std::chrono::high_resolution_clock::time_point next_minute = now + one_minute;   

    std::chrono::high_resolution_clock::time_point last_minute = now - one_minute;  

    std::chrono::high_resolution_clock::time_point next_day = now + one_day;
    std::chrono::high_resolution_clock::time_point last_day = now - one_day;
     
    std::time_t ut_now = std::chrono::high_resolution_clock::to_time_t(now);
    std::time_t ut_next_minute =  std::chrono::high_resolution_clock::to_time_t(next_minute);
    std::time_t ut_last_minute = std::chrono::high_resolution_clock::to_time_t(last_minute);
    std::time_t ut_next_day = std::chrono::high_resolution_clock::to_time_t(next_day);
    std::time_t ut_last_day = std::chrono::high_resolution_clock::to_time_t(last_day);
     
    std::cout << "now: " << ctime(&ut_now);
    std::cout << "next minute: " << ctime(&ut_last_minute);
    std::cout << "last minute: " << ctime(&ut_next_minute);
    std::cout << "next day: " << ctime(&ut_last_day);
    std::cout << "last day: " << ctime(&ut_next_day);

                The above code first obtains the current time (time_point) now, and then constructs the time interval objects one_minute and one_day, which represent one minute and one day respectively, and then adds and subtracts one_minute and one_day from the current time to get the previous minute and next One minute, this moment yesterday, this moment tomorrow (time_point);


  stl has constructed the data structure of hours, minutes, seconds, milliseconds, microseconds, and nanoseconds, so you don't need to construct it yourself through std::ratio:

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;

            For example, the following examples represent the sleep of the current thread for one second, 1000 milliseconds, and 1 microsecond:

std::this_thread::sleep_for(std::chrono::seconds(1));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::this_thread::sleep_for(std::chrono::microseconds(1));

            The time interval duration can not only be used for addition and subtraction by time_point, but also can be used for addition and subtraction between durations, such as:

std::chrono::seconds tm_span1(10);
std::chrono::minutes tm_span2(1);
std::chrono::seconds tm_span3 = tm_span2 - tm_span1;
std::cout << tm_span3.count() << std::endl;

                First define 10 seconds tm_span1 in seconds, and then define 1 minute tm_span2 in minutes, the difference between the two is 50 seconds, tm_span2-tm_span1 = 50 seconds are assigned to tm_span3 defined in seconds;

               Note: directly assigning tm_span2-tm_span1 to tm_span4 defined in minutes will cause a compilation error. If you want to assign a value, you need to do structure conversion through duration_cast:   

std::chrono::seconds tm_span1(10);
std::chrono::minutes tm_span2(1);
std::chrono::minutes tm_span4 = std::chrono::duration_cast<std::chrono::minutes>(tm_span2 - tm_span1);
std::cout << tm_span4.count() << std::endl;

     The count method of duration is the result of dividing the length of the time interval represented by the duration by its nominal unit. As in the above example, tm_span3 represents a length of 50 seconds, and its time unit is 1 second, so the result obtained by the count method is 50.

Guess you like

Origin blog.csdn.net/sunlin972913894/article/details/103194920