C11工具类:时间处理

  C++11提供时间管理类,包括三种类型:时间间隔duration,时钟clocks,时间点time point。

1、记录时常的duration

1.1 原型

  duration表示一段时间间隔,用来记录时间长度,可以表示时分秒等单位。其原型如下:

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

  Rep表示一个数值类型,表示时钟数的类型,第二个参数表示始终周期。

  std::ratio原型如下:

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

  std::ratio表示时钟周期的秒数,Num表示分子,Denom表示分母,分母默认为1,分数值表示秒数。

ratio<2>          //2秒
ratio<60>         //一分钟
ratio<60*60>      //一小时
ratio<60*60*24>        //一天
ratio<1, 1000>         //一毫秒
ratio<1, 1000000>      //一微秒
ratio<1, 1000000000>   //一纳秒

  标准库还定义了一些常用的时间间隔:

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));         //休眠3秒
std::this_thread::sleep_for(std::chrono::milliseconds(100));  //休眠100毫秒

1.2 运算

1.2.1 统计

  chrono提供获取时间间隔的时钟周期的方法count()。

#include <iostream>
#include <chrono>

using namespace std;

int main()
{
    //3毫秒
    std::chrono::milliseconds ms{3};
    std::cout << "3 ms duration has " << ms.count() << " ticks." << std::endl;

    //通过3毫秒初始化6000微秒
    std::chrono::microseconds us = 2*ms;
    std::cout << "6000 us duration has " << us.count() << " ticks." << std::endl;

    //自定义一个时钟周期
    std::chrono::duration<double, std::ratio<1, 30>> hz30{3.5};
    std::cout << "3.5 hz duration has " << hz30.count() << " ticks." << std::endl;

    return 0;
}

//执行结果
3 ms duration has 3 ticks.
6000 us duration has 6000 ticks.
3.5 hz duration has 3.5 ticks.

1.2.2 间隔运算

  时间间隔可以做运算,计算两段时间的差值。

std::chrono::minutes t1{10};        //10分钟
std::chrono::seconds t2{60};        //60秒
std::chrono::seconds t3 = t1 - t2;

std::cout << t3.count() << " seconds." << std::endl;
//输出
540 seconds.

  duration也有一套自己的运算规则,当两个duration始终周期不同的时候,会统一成一种时钟,然后再做运算。其规则如下:

  对于ratio<x1, y1> r1,ratio<x2, y2> r2;如果x1、x2最大公约数为x,y1、y2最大公约数为y,那么统一之后的ratio为ratio<x,y>。

#include <iostream>
#include <chrono>
#include <typeinfo>

using namespace std;

int main()
{
    std::chrono::duration<double, std::ratio<9, 7>> d1{3};
    std::chrono::duration<double, std::ratio<6, 5>> d2{1};
    auto d3 = d1 - d2;

    std::cout << "typeid:" << typeid(d3).name() << std::endl;
    std::cout << d3.count() << std::endl;

    return 0;
}
//执行结果
typeid:std::chrono::duration<double, std::ratio<3, 35>>
31

  根据规则,7/9和6/5,分子最大公约数为3,分母最小公倍数为35,所以统一之后的duration为std::chrono::duration<double, std::ratio<3, 35>>,所以始终周期为((7/9)/(3/35)*3) - ((6/5)/(3/35)*1) = 31。

1.2.3 转换

  可以通过duration_cast<>()来将当前的时钟周期转换为其它的时钟周期。

//将秒转换为分钟数
std::chrono::seconds ts{600};
std::cout << std::chrono::duration_cast<std::chrono::minutes>(ts).count() << " minutes." << std::endl;
//执行结果
10 minutes.

2、时间点的表示

  time_point表示一个时间点,用来获取从它的clock的纪元开始所经过的duration(比如从1970.1.1开始计算)和当前的时间。time_point可以和ctime结合起来显示时间,必须用clock来计时。time_point有一个函数time_from_eproch()用来获得纪元到time_point时间经过的duration。

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main()
{
    typedef duration<int, ratio<60*60*24>> days_type;

    time_point<system_clock, days_type> today = time_point_cast<days_type>(system_clock::now());

    cout << today.time_since_epoch().count() << endl;

    return 0;
}
//执行结果
17460

  time_point还支持一些算术运算,比如两个time_point的差值时钟周期数,还可以和duration相加减,但是必须是相同的clock。

#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>

using namespace std;
using namespace std::chrono;

int main()
{
    typedef duration<int, ratio<60*60*24>> days_type;

    system_clock::time_point now = system_clock::now();
    time_t last = system_clock::to_time_t(now - hours(24));
    time_t next = system_clock::to_time_t(now - hours(24));

    cout << "last day: " << put_time(localtime(&last), "%c") << endl;
    cout << "next day: " << put_time(localtime(&next), "%c") << endl;

    return 0;
}
//执行结果
last day: 10/20/17 23:05:50
next day: 10/20/17 23:05:50

3、获取系统时钟的clocks

  • clocks表示当前的系统时钟,内部有time_point、duration、Rep、Period等信息,主要用来获取当前时间,以及事项time_t和time_point的相互转换。clocks包括如下三种时钟:
  • system_clock:表示真实世界的挂钟时间,具体时间依赖于系统。
  • steady_clock:不能被“调整”的时钟,并不一定代表真实世界的挂钟时间,保证先后调用now()的得到的时间值是不会递减的。
  • high_resolution_clock:高精度时钟,实际上system_clock或者steady_clock的别名,可以通过nowlai 获取当前的时间点。
#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main()
{
    system_clock::time_point t1 = system_clock::now();
    cout << "hello world." << endl;
    system_clock::time_point t2 = system_clock::now();
    cout << (t2-t1).count() << " tick count."<< endl;

    return 0;
}
//执行结果:
hello world.
10001 tick count.

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

cout << duration_cast<microseconds> (t2-t1).count() << " microseconds."<< endl;
//输出结果:
hello world.
1000 microseconds.

  system_clock的to_time_t可以将一个time_point转换为ctime,而from_time_t方法则可以将ctime转换为time_point。

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

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

  system_clock和std::put_time配合起来使用可以格式化日期的输出。

#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main()
{
    auto t = system_clock::to_time_t(system_clock::now());

    cout << put_time(localtime(&t), "%Y-%m-%d %X") << endl;
    cout << put_time(localtime(&t), "%Y-%m-%d %H.%M.%S") << endl;

    return 0;
}
//执行结果:
2017-10-29 21:19:30
2017-10-29 21.19.30

4、计时器timer

  可以利用high_resolution_clock来实现一个类似于boost.timer的计时器,这样的timer在测试性能的时候经常用到。在程序日常开发的时候可以作为测试函数耗时。

void func()
{
    //dosomething...
}

int main()
{
    Timer t; //开始计时
    func();
    cout << t.elapsed() << endl; //打印func函数耗时
}

  C++中可以通过chrono库来事项一个计时器,从而移除对其他三方库的依赖。

#include <ctime>
#include <iomanip>
#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

class CTimer
{
public:
    CTimer() : m_begin(high_resolution_clock::now()) {}

    //重置
    void mvReset() { m_begin = high_resolution_clock::now();  }

    //默认输出毫秒
    template<typename Duration = milliseconds>
    int64_t elapsed() const
    {
        return duration_cast<Duration>(high_resolution_clock::now() - m_begin).count();
    }

    //微秒
    int64_t elapsed_micro() const
    {
        return elapsed<microseconds>();
    }

    //纳秒
    int64_t elapsed_nano() const
    {
        return elapsed<nanoseconds>();
    }

    //秒
    int64_t elapsed_sconds() const
    {
        return elapsed<seconds>();
    }

    //分
    int64_t elapsed_minutes() const
    {
        return elapsed<minutes>();
    }

    //时
    int64_t elapsed_hours() const
    {
        return elapsed<hours>();
    }

private:
    time_point<high_resolution_clock> m_begin;
};

//test func
void func()
{
    cout << "hello world." << endl;
}

int main()
{
    CTimer t;
    func();
    cout << t.elapsed() << endl;                       //打印func函数耗时毫秒
    cout << t.elapsed_micro() << endl;                 //打印func函数耗时微秒
    cout << t.elapsed_nano() << endl;                  //打印func函数耗时纳秒
    cout << t.elapsed_sconds() << endl;                //打印func函数耗时秒
    cout << t.elapsed_minutes() << endl;               //打印func函数耗时分
    cout << t.elapsed_hours() << endl;                 //打印func函数耗时小时

    return 0;
}
//执行结果
hello world.
1
1000
1000000
0
0
0
时间: 2024-08-02 19:55:27

C11工具类:时间处理的相关文章

C11工具类:字符转换

1.数值类型和字符串转换 1.1 数值转换为字符 std::string to_string(int value); std::string to_string(long value); std::string to_string(long long value); std::string to_string(unsigned value); std::string to_string(unsigned long value); std::string to_string(unsigned lo

nodejs时间工具类

/** * * @fmt 格式化字符串 * @Date 为需要格式化的日期 * * 示例:format(new Date(),'yyyy-MM-dd hh:mm:ss'); * 返回值为字符串 */ function dateFormat (date,fmt) { var o = { "M+": date.getMonth() + 1, //月份 "d+": date.getDate(), //日 "h+": date.getHours(), /

时间日期工具类

本工具类主要内容是LocalDateTime与Date的互转以及与日期字符串的相互转换,可与commons-lang-xxx.jar中提供的DateUtils配合使用 import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Date; public class DateTimeUtils { /** * 格式化LocalDateTime实例为日期时间字符串 * * @param localDa

Java日期工具类,Java时间工具类,Java时间格式化

Java日期工具类,Java时间工具类,Java时间格式化 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright  蕃薯耀 2017年2月4日 15:03:27 星期六 http://www.cnblogs.co

StringUtil工具类 之 时间格式化函数

/** * 时间格式化函数,默认为yyyy-MM-dd HH:mm:ss *<b>Summary: </b> * formatDate() * @param date * @param formate * @return */ public static String formatDate(Date date,String formate){ SimpleDateFormat sdf = null; if(date == null){ return ""; }

为大家提供一个好的时间工具类DateTime

此类的灵感来源于C# 尽管网上有什么date4j,可是jar太纠结了.先给出源代码,能够继承到自己的util包中.作为一个资深程序猿,我相信都有不少好的util工具类,我也希望经过此次分享,能带动技术大牛们能分享出自己的好用的工具类. 先看源代码 /* * 岸思科技开发平台(JAVA) SDK * * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved. * http://www.ansitech

Java获取时间 时间计算 转换时间工具类

Java获取时间 时间计算 转换时间工具类 JAVA日期工具类 package com.mh.util; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * 时间日期转换工具类 */ public class DateTimeUtil { /** *

时间转化工具类

/**  * 时间转换工具类  * @author Lin LI  * @DATE 2015-08-26  */ public class Test { public static void main(String[] args) { //转换格式:天-时-分-秒 secTime(60*60);   // 传入单位秒 // 转换格式:天-时-分-秒-毫秒 diffTime(2800);   // 传入单位毫秒 } /**  * 转换格式:天-时-分-秒  * @param secTime  */

java时间比较工具类分享

开发中经常需要比较时间,写了一个简易的工具类,分享一下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76