一、实现思路
1)C语言获取当前时间(精确到秒)
C语言中,使用std::time函数和std::localtime函数可以获取当前时间(精确到秒)。详情见《标准库头文件 ctime》
核心代码:
#include
std::time_t seconds_since_epoch = std::time(nullptr); // 获取从1970-01-01 00:00:00到现在的秒数
std::tm current_time = *std::localtime(&seconds_since_epoch); // 获取当前时间(精确到秒)
2)C++11获取当前时间(精确到微妙)
使用C++11新加入std::chrono库可以获取精确到微妙的当前时间。详情见《标准库头文件 chrono》
核心代码:
#include
#include
using namespace std::chrono;
system_clock::time_point time_point_now = system_clock::now(); // 获取当前时间点
system_clock::duration duration_since_epoch
= time_point_now.time_since_epoch(); // 从1970-01-01 00:00:00到当前时间点的时长
time_t microseconds_since_epoch
= duration_cast<microseconds>(duration_since_epoch).count(); // 将时长转换为微秒数
time_t seconds_since_epoch = microseconds_since_epoch / 1000000; // 将时长转换为秒数
std::tm current_time = *std::localtime(&seconds_since_epoch); // 获取当前时间(精确到秒)
time_t tm_microsec = microseconds_since_epoch % 1000; // 当前时间的微妙数
time_t tm_millisec = microseconds_since_epoch / 1000 % 1000; // 当前时间的毫秒数
二、C++代码实现
1)exact_time.hpp
/*
* Copyright(C) 2016-2020
* Filename: exact_time.hpp
* Author: L.Y.
* Contact: [email protected]
* Brief: 精确时间类,精确到微妙;用于取代Windows库中的SYSTMTIME
* Dependencies: C++11
* Update log:
* 1) 20200410-20200413 V1.0.0
* 1, 初次版本,精确时间类,精确到微妙;用于取代Windows库中的SYSTMTIME。
* 2) 20200629 V2.0.0
* 1, 去除opencv库的依赖。
* 2, 更改成员函数,使接口更加清晰。
* 3) 20200629 V2.0.1
* 1, bug1:std::localtime函数多线程不安全,导致currentTime函数多线程不安全。
* 解决方法:使用静态的互斥锁。
* 4) 20200724 V2.0.2
* 1, bug2: 使用静态的互斥锁,不能完全解决bug1。解决方法:删除静态的互斥锁,
* std::localtime改为std::localtime_s(WIndows)和std::localtime_r(Linux)。
* 2, 功能优化:编译器为MS VC++时,使用sprintf_s取代sprintf。
* 5) 20200824 V2.0.3
* 1, 代码优化:使用snprintf函数取代sprintf函数。
* 6) 20200929 V2.1.0
* 1, 功能增加:增加公有成员函数toStringForFilename。
* 7) 20201112 V2.2.0
* 1, 代码优化:去除“数据成员设置函数”。
* 2, 接口增加:新增构造函数ExactTime(const std::tm&, int, int)。
* Performance:
* 1) 获取当前时间耗时(@i7-6700k):C++ API:10e-7ms; Windows API:5.5e-7ms。
* TODO:
* 1)) 20200413 currentTime函数可以设定精度:分、秒、毫秒、微妙。
* 2)) 20200707 自己实现std::localtime函数,去除条件预编译。
* 3) 20200724 自己实现format函数,用于取代sprintf函数。(V2.0.3)
*/
#ifndef EXACT_TIME_HPP
#define EXACT_TIME_HPP
#include
#include
namespace ly {
//
// \brief: 精确时间类
//
class ExactTime : public std::tm
{
public:
int tm_millisec; // 毫秒
int tm_microsec; // 微秒
//! 默认构造函数
ExactTime();
//! 构造函数(重载)
ExactTime(const std::tm& _tm, int _tm_millisec, int _tm_microsec);
//! 转换为字符串(此字符串含有':',不能用于文件名)
std::string toString() const;
//! 转换为字符串,可用于文件名
std::string toStringForFilename() const;
//! 获取当前时间
static ExactTime currentTime();
protected:
private:
};
} // namespace
#endif // EXACT_TIME_HPP
2)exact_time.cpp
/*
* Copyright(C) 2016-2020
* Filename: exact_time.cpp
* Author: L.Y.
* Contact: [email protected]
* Brief: 精确时间类,精确到微妙;用于取代Windows库中的SYSTMTIME
* Dependencies: C++11
* Update log:
* 1) 20200410-20200413 V1.0.0
* 1, 初次版本,精确时间类,精确到微妙;用于取代Windows库中的SYSTMTIME。
* 2) 20200629 V2.0.0
* 1, 去除opencv库的依赖。
* 2, 更改成员函数,使接口更加清晰。
* 3) 20200629 V2.0.1
* 1, bug1:std::localtime函数多线程不安全,导致currentTime函数多线程不安全。
* 解决方法:使用静态的互斥锁。
* 4) 20200724 V2.0.2
* 1, bug2: 使用静态的互斥锁,不能完全解决bug1。解决方法:删除静态的互斥锁,
* std::localtime改为std::localtime_s(WIndows)和std::localtime_r(Linux)。
* 2, 功能优化:编译器为MS VC++时,使用sprintf_s取代sprintf。
* 5) 20200824 V2.0.3
* 1, 代码优化:使用snprintf函数取代sprintf函数。
* 6) 20200929 V2.1.0
* 1, 功能增加:增加公有成员函数toStringForFilename。
* 7) 20201112 V2.2.0
* 1, 代码优化:去除“数据成员设置函数”。
* 2, 接口增加:新增构造函数ExactTime(const std::tm&, int, int)。
* Performance:
* 1) 获取当前时间耗时(@i7-6700k):C++ API:10e-7ms; Windows API:5.5e-7ms。
* TODO:
* 1)) 20200413 currentTime函数可以设定精度:分、秒、毫秒、微妙。
* 2)) 20200707 自己实现std::localtime函数,去除条件预编译。
* 3) 20200724 自己实现format函数,用于取代sprintf函数。(V2.0.3)
*/
#include "exact_time.hpp"
#include
using namespace std::chrono;
namespace ly {
ExactTime::ExactTime()
: tm_millisec(0),
tm_microsec(0)
{
}
ExactTime::ExactTime(const std::tm& _tm, int _tm_millisec, int _tm_microsec)
: std::tm(_tm),
tm_millisec(_tm_millisec),
tm_microsec(_tm_microsec)
{
}
std::string ExactTime::toString() const
{
char temp[27]{ 0 };
snprintf(temp,
27,
"%04d-%02d-%02d %02d:%02d:%02d.%03d%03d",
tm_year + 1900,
tm_mon + 1,
tm_mday,
tm_hour,
tm_min,
tm_sec,
tm_millisec,
tm_microsec);
return std::string(temp);
}
std::string ExactTime::toStringForFilename() const
{
char temp[27]{ 0 };
snprintf(temp,
27,
"%04d-%02d-%02d %02d_%02d_%02d.%03d%03d",
tm_year + 1900,
tm_mon + 1,
tm_mday,
tm_hour,
tm_min,
tm_sec,
tm_millisec,
tm_microsec);
return std::string(temp);
}
ExactTime ExactTime::currentTime()
{
system_clock::time_point time_point_now = system_clock::now(); // 获取当前时间点
system_clock::duration duration_since_epoch
= time_point_now.time_since_epoch(); // 从1970-01-01 00:00:00到当前时间点的时长
time_t microseconds_since_epoch
= duration_cast<microseconds>(duration_since_epoch).count(); // 将时长转换为微秒数
time_t seconds_since_epoch = microseconds_since_epoch / 1000000; // 将时长转换为秒数
#if defined _MSC_VER && _MSC_VER >= 1400
ExactTime exact_time;
localtime_s(&exact_time, &seconds_since_epoch);
exact_time.tm_microsec = microseconds_since_epoch % 1000;
exact_time.tm_millisec = microseconds_since_epoch / 1000 % 1000;
#elif defined __GNUC__
ExactTime exact_time;
localtime_r(&seconds_since_epoch, &exact_time);
exact_time.tm_microsec = microseconds_since_epoch % 1000;
exact_time.tm_millisec = microseconds_since_epoch / 1000 % 1000;
#else
ExactTime exact_time(*std::localtime(&seconds_since_epoch),
microseconds_since_epoch / 1000 % 1000,
microseconds_since_epoch % 1000);
#endif
return exact_time;
}
} // namespace
3)main.cpp
/*
* Filename: main.cpp
* Author: L.Y.
* Brief: ExactTime类测试
*/
#include
#include "exact_time/exact_time.hpp"
using namespace ly;
int main()
{
ExactTime exact_time = ExactTime::currentTime();
std::cout << "当前时间:" << exact_time.toString();
getchar();
return 0;
}