使用Boost::ptime构建高精度计时器
1. 时间点
Boost::ptime 被称为时间点,整合了日期与微秒或纳秒,是十分方便的时间工具类。
2. 构造ptime
ptime p(date(2019,9,9),hours(12)+minutes(30)+seconds(11));
cout<<p1<<endl;
//输出:2019-Sep-09 12:30:00
当然,hours、minutes、seconds可以部分不写也可以全部不写,构造函数会默认为00:00:00。
3. 获取当前时间
ptime p3=second_clock::local_time(); //获取当地时间(秒) ptime p4=microsec_clock::universal_time(); //获取UTC时间(微秒) ptime p5=microsec_clock::local_time(); //获取当地时间(微秒) cout<<p3<<endl; cout<<p4<<endl; cout<<p5<<endl;
4. string与date的互转化
- string to date
ptime p1 = time_from_string("1999-12-31 01:00:00"); ptime p2 = from_iso_string("20011118T010000") ; cout << p1 << p2 << endl;
- date to string
cout << to_simple_string(p) << endl; //转化为YYYY-mmmm-DD HH:MM:SS.ffffff,其中mmmm为英文缩写 cout << to_iso_string(p) << endl; //转化为YYYYMMDDTHHMMSS,ffffff格式的数字字符串 cout << to_iso_extended_string(p) << endl; //转化为YYYY-MM-DDTHH:MM:SS,ffffff的数字字符串
5. 构建高精度计时器
template<typename Clock = microsec_clock> class basic_ptimer{ public: basic_ptimer(std::ostream &os=std::cout):_os(os){ restart(); } void restart(){ _start_time=Clock::local_time(); } const time_duration elapsed()const{ return Clock::local_time()-_start_time; } ~basic_ptimer(){ try{ std::istream::fmtflags old_flags=_os.setf(std::istream::fixed, std::istream::floatfield); std::streamsize old_prec=_os.precision(2); cout<<elapsed()<<" s\n"<<endl; _os.flags(old_flags); _os.precision(old_prec); }catch(...){} } private: ptime _start_time; std::ostream &_os; }; using ptimer=basic_ptimer<microsec_clock>; //微秒 using sptimer=basic_ptimer<second_clock>; //秒
5. 重定向s输出
上面我们实现了高精度计时器basic_ptimer,我们可以重定向basic_ptimer的输出,一般有两种方法:
- 利用cout.rebuf()重定向
std::streambuf *psbuf, *backup; std::ofstream filestr; filestr.open ("test.txt"); backup = std::cout.rdbuf(); // back up cout's streambuf psbuf = filestr.rdbuf(); // get file's streambuf std::cout.rdbuf(psbuf); // assign streambuf to cout std::cout << "This is written to the file"; std::cout.rdbuf(backup); // restore cout's original streambuf filestr.close();
- 构造时,指定其他ostream
相对于前面的方法,这种更常见。下面的代码展示它的便捷:
stringstream ss;
{
progress_timer t(ss);
}
cout<<ss.str();
这两个方法同样适合计时器progress_timer。
整个程序的代码:
#include <iostream> #include <boost/date_time/gregorian/gregorian.hpp> #include <boost/date_time/posix_time/posix_time.hpp> using namespace std; using namespace boost::posix_time; using namespace boost::gregorian; void case1(){ ptime p(date(2017,7,7),hours(1)); ptime p1=time_from_string("2017-7-7 01:00:00"); ptime p2=from_iso_string("20170707T010000"); ptime p3=second_clock::local_time(); ptime p4=microsec_clock::universal_time(); ptime p5=microsec_clock::local_time(); cout<<p1<<endl; cout<<p2<<endl; cout<<p3<<endl; cout<<p4<<endl; cout<<p5<<endl; cout<<to_iso_extended_string(p5)<<endl; //和date一致 } template<typename Clock = microsec_clock> class basic_ptimer{ public: basic_ptimer(std::ostream &os=std::cout):_os(os){ restart(); } void restart(){ _start_time=Clock::local_time(); } const time_duration elapsed()const{ return Clock::local_time()-_start_time; } ~basic_ptimer(){ try{ std::istream::fmtflags old_flags=_os.setf(std::istream::fixed, std::istream::floatfield); std::streamsize old_prec=_os.precision(2); cout<<elapsed()<<" s\n"<<endl; _os.flags(old_flags); _os.precision(old_prec); }catch(...){} } private: ptime _start_time; std::ostream &_os; }; using ptimer=basic_ptimer<microsec_clock>; using sptimer=basic_ptimer<second_clock>;
int main(){ ptimer t; sptimer t1; case1(); sleep(1); return 0; }