首页 > 编程语言 >[c++11新特性]09-chrono的使用与封装

[c++11新特性]09-chrono的使用与封装

时间:2022-12-06 17:04:26浏览次数:55  
标签:11 std clock 09 timer tm time chrono

时间类的简介

  • ​时间类的简介​
  • ​​duration 简介​​
  • ​​借助 chrono 实现的定时器​​
  • ​​time_point​​
  • ​时间类的封装​
  • ​​时间格式化​​
  • ​​日期变化​​

duration 简介

duration用来度量时间长度。在chrono类中有多个精度的duration。其模板定义如下:

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

};

其中Rep代表一个整型,比如int32,int64等。std::ratio<T,U>则代表时间精度,ratio<1,1>表示时间精度为秒。以下为常见的时间精度:

typedef ratio<1,                1000000000> nano;   // 纳秒
typedef ratio<1, 1000000> micro; // 微妙
typedef ratio<1, 1000> milli; // 毫秒

typedef duration<int64_t, nano> nanoseconds;// 纳秒
typedef duration<int64_t, micro> microseconds;/// 微秒
typedef duration<int64_t, milli> milliseconds;/// 毫秒
typedef duration<int64_t> seconds;/// 秒
typedef duration<int64_t, ratio< 60>> minutes;/// 分钟
typedef duration<int64_t, ratio<3600>> hours;/// 小时

通过chrono可以很方便的自定义各种精度单位:

using hz60 = duration<int64_t,ratio<1,60>>; /// 60HZ
using days = duration<int64_t,ratio<24*60*60,1>>;/// 一天
using weaks= duration<int64_t,ratio<7*24*60*60*60,1>>;/// 一星期

并且,chrono还提供了不同类型之间的加减操作,如下所示:

auto second = std::chrono::seconds(100);    /// 100秒
auto hour = std::chrono::hours(2); /// 2个小时
std::chrono::seconds new_seconds = hour - second; /// 得到一个以秒为单位的duration
new_durations.count(); // hour - second 之间有多少秒

std::chrono::mimutes mimut = hour - second; /// hour 和 second 之差转换为以分为单位的duration

借助 chrono 实现的定时器

借助于 chrono 可以很方便的实现一个定时器,该定时器提供任意精度的度量——通过模板函数指定Duration实现。

#include <string>
#include <map>
#include <iostream>
#include <chrono>
#include <thread>


class timer
{
public:
timer():m_clock(std::chrono::high_resolution_clock::now()){}

template<class Duration>
int64_t escaped()
{
return std::chrono::duration_cast<Duration>(std::chrono::high_resolution_clock::now() - m_clock).count();
}
private:
std::chrono::high_resolution_clock::time_point m_clock;
};

// std::chrono::nanoseconds
// std::chrono::milliseconds
// std::chrono::seconds
// std::chrono::minutes
// std::chrono::hours
// std::chrono::duration<long long,std::ratio<86400>>
template<class Duration>
class timer_scope
{
public:
timer_scope(const std::string &msg = ""):m_msg(msg){}
~timer_scope()
{
std::cout << "timer_scope,escaped:" << m_timer.escaped<Duration>() << " " << m_msg << std::endl;
}
private:
std::string m_msg;
timer m_timer;
};


int main()
{
if (false)
{
timer t;
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << t.escaped<std::chrono::seconds>() << std::endl;
}

if (true)
{
timer_scope<std::chrono::nanoseconds> ns_timer(" ns"); // timer_scope,escaped:2000999100 ns
timer_scope<std::chrono::milliseconds> ms_timer(" ms"); // timer_scope,escaped:2001 ms
timer_scope<std::chrono::seconds> second_timer(" s"); // timer_scope,escaped:2 s
timer_scope<std::chrono::duration<long long,std::ratio<86400>>> day_timer(" day"); // timer_scope,escaped:0 day


std::this_thread::sleep_for(std::chrono::seconds(2));
}

return 0;
}

time_point

time_point表示时间点,chrono 提供了3种不同的 clock 来表示 time_point,它们分别是:

  • std::chrono::system_clock : 系统时钟
  • std::chrono::steady_clock : 稳定时钟
  • std::chrono::high_resolution_clock : 高分辨率时钟,一般情况下就是 system_clock

通过上面的三个类,可以很容易的获取当前时间点对应的time_point,并且为了兼容 c 风格的函数,还提供了 time_point 和 time_t 相互转换的接口,如下:

using clock = std::chrono::system_clock;
auto now = clock::now(); // 获取当前的时间点 time_point
time_t t = clock::to_time_t(now); // 返回一个 time_t

auto last_time_point = clock::from_time_t(t); // 返回一个 time_point

时间类的封装

  • [格式化时间]
  • [简单的定时器]
  • [日期变化]

时间格式化

// 缺省格式:YYYY-MM-DD HH-MM-SS
// 其他格式见满手册: man strftime
static std::string format_time(std::string formt = std::string{"%F %T"})
{
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::stringstream ss;
struct tm tm;
//localtime_s(&tm,&t);
localtime_r(&t,&tm);
//ss << std::put_time(&tm, formt.c_str()); // at least g++ 5.0
char sztime[256] = {0};
if(strftime(sztime,sizeof(sztime),formt.c_str(),&tm) > 0)
{
ss << sztime;
}

return ss.str();
}
std::string format_time(time_t t)
{
struct tm result;
localtime_r(&t,&result);
char sztime[48];
snprintf(sztime,sizeof(sztime),"%4d-%02d-%02d %02d:%02d:%02d",result.tm_year + 1900,result.tm_mon,result.tm_mday,result.tm_hour,result.tm_min,result.tm_sec);
return sztime;
}

日期变化

time_point 表示时间点,通过 to_time_t 函数可以将一个时间点转换为 time_t。

class date
{
using clock = std::chrono::system_clock;
public:
date():m_clock(clock::time_point::now()){}

bool hour_changed() const
{
time_t now = clock::to_time_t(clock::now());
struct tm current_tm;
localtime_s(&current_tm,&now);

time_t last_time = clock::to_time_t(m_clock);
struct tm last_tm;
localtime_s(&last_tm, &last_time);
if (current_tm.tm_hour != last_tm.tm_hour || current_tm.tm_mday != last_tm.tm_mday || current_tm.tm_mon != last_tm.tm_mon || current_tm.tm_year != last_tm.tm_year)
{
return true;
}
return false;
}
private:
clock::time_point m_clock;
};

标签:11,std,clock,09,timer,tm,time,chrono
From: https://blog.51cto.com/u_6650004/5916396

相关文章

  • 300011 绝对标高和相对标高
    <?phpheader('Content-Type:text/html;charset=utf-8');define('ROOT',$_SERVER['DOCUMENT_ROOT']);includeROOT.'/assets/php/head.php';$tit='绝对标高和相对......
  • [c++11新特性]02-模板优化
    模板优化​模板优化​​​模板别名​​​​默认模板参数​​​​外部模板​​模板别名在了解类型别名模板之前,需要理解『模板』和『类型』之间的不同。仔细体会这句话:模板是......
  • [c++11新特性]07-可变参模板
    可变参模板​​可变参数模板​​​可变参模板​​​简介​​​​递归模板函数​​简介可变参模板是c++11引入的特别重要的一个特性,和c语言中的可变参一样,也是使用...来......
  • W11中使用VScode远程开发之宝塔用户自动登录
    宝塔面板开启ssh,加密方式选择rsa下载秘钥,放值目录:C:\Users\本机用户\.ssh修改该目录下的config文件Host111.112.113.114HostName111.112.113.114UserrootF......
  • Oracle错误——ORA-03113:通信通道的文件结尾 解决办法
    该错误我是还原数据库之后出现的建议的问题跟进方法是先查看oracle的日志,查看的方法select*fromv$diag_info 先看日志文件存储在哪,根据路径找到文件查看文件内容......
  • Semaphore信号量源码解析(基于jdk11)
    目录1、Semaphore信号量源码解析(基于jdk11)1.1Semaphore概述1.2Semaphore的原理1.2.1基本结构(jdk11)1.2.2可中断获取信号量1.2.3公平模式1.2.4非公平模式1.2.4不......
  • CyclicBarrier循环屏障源码解析(基于jdk11)
    目录CyclicBarrier循环屏障源码解析(基于jdk11)1.1CyclicBarrier概述1.2CyclicBarrier原理1.2.1基本结构(jdk11)1.2.2await()方法1.2.3dowait方法1.2.3.1breakBarrie......
  • Newsletter 2022-11|HStreamDB 0.11 发布
    11月我们发布了HStreamDB0.11,修复了多项已知问题。同时也在继续推进HStreamPlatform的开发,并计划于本月底上线首个Alpha版本。v0.11发布随着云原生流数据库​​HSt......
  • Go-09 Go语言中数组、切片的排序算法以及sort包
    packagemainimport( "fmt" "sort")//Golang数组中的切片及sort包funcmain(){ //1.选择排序 varnumSlice=[]int{9,8,7,6,5,4} fori:=0;i<le......
  • [c++11新特性]02-自动类型推导
    自动类型推导在c++11中,关于类型推导的关键字有using,decltype,auto,typeid。在c++11之前我们要声明一个类型的别名往往使用的是typedef,但是该关键字在模板类型推导中存在一......