时间类的简介
- 时间类的简介
- 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(¤t_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;
};