C++11中引入了chrono命名空间来处理时间相关的功能,该功能的引入极大的方便了开发人员对时间的操作。初次接触chrono,感觉会有点陌生,下来让我带你开启chrono的使用之旅。

1.chrono包含部分

chrono中主要包含时钟,时间点和时间间隔三部分。

(1)时钟

std::chrono::steady_clock  //相对时钟

std::chrono::system_clock //绝对时钟

(2)时间点

std::chrono::steady_clock::time_point  //相对时间点

std::chrono::system_clock::time_point // 绝对时间点

(3)时间间隔

std::chrono::nanoseconds        //纳秒
std::chrono::microseconds       //微妙
std::chrono::milliseconds       //毫秒
std::chrono::seconds            //秒
std::chrono::minutes            //分
std::chrono::hours              //时

2.chrono使用

#include <iostream>
#include <ctime>
#include <iomanip> //std::put_time  std::get_time
#include <chrono>
#include <sstream>
#include <thread>  //std::this_thread::sleep_for
#include <sys/time.h>

void testTime() {
    //时间间隔: duration 时钟: clocks   时间点: time point
    //计算时间间隔,相对时间
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    std::chrono::nanoseconds ndur = end - begin;
    std::cout << ndur.count() << std::endl;
    // 时间间隔默认是纳秒,要计算到秒,需要使用chrono自带的强制转换类型
    std::chrono::seconds sdur = std::chrono::duration_cast<std::chrono::seconds>(end - begin);
    std::cout << sdur.count() << std::endl;

    //获取系统时间,绝对时间,time_point与time_t互转, 显示时间
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    //获取两天以后的时间,得到time_t类型
    time_t after = std::chrono::system_clock::to_time_t(now + std::chrono::hours(48));
    std::chrono::system_clock::time_point after_point = std::chrono::system_clock::from_time_t(after);
    //打印两天以后的经过的纳秒
    std::cout << (after_point - now).count() << std::endl;
    std::cout << std::chrono::duration_cast<std::chrono::hours>(after_point - now).count() << std::endl;

    //时间格式化
    std::time_t seond_now = std::chrono::system_clock::to_time_t(now);
    std::stringstream ss;

    //time_t -> ss
	ss << std::put_time(std::localtime(&seond_now), "%Y-%m-%d %H:%M:%S");
    std::string strTime = ss.str();
    std::cout << "put_time::" << strTime << std::endl;
    std::cout << std::put_time(std::localtime(&seond_now), "%F %T") <<std::endl;
    std::cout << ss.str() << std::endl;

    time_t rawtime;
	struct tm info;
    //std::localtime是非线程安全的,linux下建议使用localtime_r,windows下使用localtime_s
    localtime_r(&seond_now, &info);//将time_t转为tm

    char buffer[80];
    //ctime是非线程安全的,C标准也建议使用strftime,不要使用ctime、ctime_s
    std::strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", &info);
    std::cout << "strftime::" << buffer << std::endl;

    struct tm tm_now;
    //ss -> tm
	ss >> std::get_time(&tm_now, "%Y-%m-%d %H:%M:%S");

    strTime = ss.str();
    std::cout << "get_time:: " << strTime << std::endl;

    //将tm转为time_t
    time_t dd = std::mktime(&tm_now);
    std::cout << "mktime::" << dd << std::endl;

    //时间戳打印显示
    //utc
    uint64_t seconds1 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << seconds1 << std::endl;
    //相对时间
    uint64_t seconds2 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
    std::cout << seconds2 << std::endl;

    struct timeval tv;
    gettimeofday(&tv, NULL);
    //秒
    uint64_t timestamp1 = tv.tv_sec;
    //毫秒
    uint64_t timestamp2 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    //微秒
    uint64_t timestamp3 = tv.tv_sec * 1000 * 1000 + tv.tv_usec;
    std::cout << timestamp1 << " " << timestamp2 << " " << timestamp3 << std::endl;
    printf("%ld, %ld, %ld\n", timestamp1, timestamp2, timestamp3);

    timestamp1 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    timestamp2 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    timestamp3 = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << timestamp1 << " " << timestamp2 << " " << timestamp3 << std::endl;
    printf("%ld, %ld, %ld\n", timestamp1, timestamp2, timestamp3);
}

int main ()
{
    testTime();
    return 0;
}

运行结果如下:

 

说明:

(1)chrono没有提供时间格式化的操作,格式得到指定格式的字符串需要使用std::put_time或者std::strftime 

(2)std::localtime返回静态struct tm *类型对象,是非线程安全的,所以为了程序的健壮性,在linux下使用localtime_r,windows下使用localtime_s

(3)std::put_time时间可以存放在stringstream中,std::get_time从stringstream中获取时间信息,其使用是对应的

(4)std::chrono::steady_clock:相对时钟,不会因为修改了系统时间而变化,功能类似于平时生活中的计时秒表。std::chrono::system_clock是系统时钟,对系统有依赖,系统时间修改其也会发生变化。所以std::chrono::steady_clock在实际开发中用来统计耗时,std::chrono::system_clock用来获取系统时间。chrono

Logo

更多推荐