C++11获取系统当前时间(精确到微秒)

9 篇文章 4 订阅
本文介绍了如何在C++中获取当前时间,包括C语言和C++11两种方式,精确到秒和微妙。同时,详细解析了一个名为`ExactTime`的C++类,该类用于实现精确到微妙的时间,并提供了转换为字符串的方法,适用于文件命名。文章还包含了类的实现细节,如线程安全和性能优化。
摘要由CSDN通过智能技术生成


一、实现思路

1)C语言获取当前时间(精确到秒)
C语言中,使用std::time函数和std::localtime函数可以获取当前时间(精确到秒)。详情见《标准库头文件 ctime》
核心代码:

#include <ctime>

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 <chrono>
#include <ctime>
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: qwetuqq@outlook.com
 * 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 <ctime>
#include <string>

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: qwetuqq@outlook.com
 * 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 <chrono>

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 <iostream>

#include "exact_time/exact_time.hpp"

using namespace ly;

int main()
{
    ExactTime exact_time = ExactTime::currentTime();
    std::cout << "当前时间:" << exact_time.toString();
    getchar();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值