【cc++】linux时间获取与时间转换函数总结

【cc++】linux时间获取与时间转换函数总结,第1张

1. 序言

程序中常需要记录时间戳或者计算模块耗时,在此对时间函数及应用场景做一个总结

2. 有哪些函数
  • 获取时间

    clock, time, gettimeofday, chrono库时间函数

  • 时间格式转换

    ctime, localtime, gmtime, asctime, mktime, strftime

  • 其他

    计算时间差:difftime
    时间转换线程安全函数:ctime_r, localtime_r, asctime_r, gmtime_r

3. 选用场景
  • 获取时间的函数
函数功能描述选用场景
clock从程序启动到此函数调用消耗的处理器时间,精确到微秒统计程序内模块处理器耗时
time当前的UTC时间,精确到秒统计过去了多少秒
gettimeofday当前的UTC时间,精确到微秒获取当前较精确时间戳
chrono::system_clock当前的UTC时间,精确到微秒获取当前较精确时间戳,与NTP时间有关
chrono::steady_clock当前的UTC时间,精确到纳秒获取当前稳定的高精确时间戳
chrono::high_resoluction_clock当前的UTC时间,精确到纳秒获取当前最高精确时间戳
  • 时间转换函数
函数功能描述选用场景
localtime将UTC秒数转换为本地时间(tm格式)可按年月日时分秒显示
gmtime将UTC秒数转换为本地时间(tm格式)可按年月日时分秒显示
ctime将UTC秒数转换为本地时间(字符串格式)星期 月 日 时分秒 年
asctime将tm时间转换为UTC秒数(字符串形式)星期 月 日 时分秒 年
mktime将tm格式的时间转换为UTC秒数统计过去了多少秒
strftime将tm格式的时间转换为指定格式时间转换为特定格式
  • 其他时间函数
函数功能描述选用场景
difftime统计两个时间相差的秒数计算两个UTC时间相差多少秒
ctime_r, localtime_r, asctime_r, gmtime_r当ctime, localtime, asctime, gmtime对应的线程安全函数线程安全的时间转换函数

ctime/asctime两者传入的参数结构不同,见4. 详细解析
 

4. 详细解析 4.1 时间获取函数
1. clock函数
头文件#include
函数原型clock_t clock(void)
函数说明typedef long clock_t;获取从程序启动到此函数调用消耗的处理器时间,精确到毫秒
返回值时间可用返回时间,否则返回-1
  • 使用实例
#include 
#include 
#include 
#include 	// 或 #include 
#include 
 
// function耗时工作
void function()
{
    double d = 0;
    for (int n = 0; n < 10000; ++n)
       for (int m = 0; m < 10000; ++m)
           d += d * n * m;
}
 
int main()
{
    std::clock_t clock_start = std::clock();

    auto utc_start = std::chrono::high_resolution_clock::now();

    std::thread t1(function);
    std::thread t2(function);
    t1.join();
    t2.join();
    
    std::clock_t clock_end = std::clock();
    
    auto utc_end = std::chrono::high_resolution_clock::now();
 
    std::cout << std::fixed << std::setprecision(2) << "CPU耗时: "
              << (clock_end - clock_start) / 1000.0 << " ms\n"
              << "UTC耗时: "
              << std::chrono::duration<double, std::milli>(utc_end - utc_start).count()
              << " ms\n";
}
# 编译
g++ -o main main.cpp -lpthread
# 运行
./main
2. time函数
头文件#include
函数原型time_t time(time_t* t)
函数说明typedef long time_t; 返回UTC时间,精确到秒
返回值成功返回秒数,失败返回 (time_t)-1
  • 使用实例
#include 
#include 
 
using namespace std;

int main()
{
    time_t seconds = time((time_t*)NULL);
    std::cout << seconds << std::endl;
    return 0;
}
# 编译运行
g++ -o main main.cpp
3. gettimeofday函数
头文件#include #include
函数原型int gettimeofday (struct timeval * tv , struct timezone * tz)
函数说明时间放到tv结构,时区放到tz所指结构。tz一般使用nullptr
返回值成功返回0, 失败返回-1
  • 使用实例
#include
#include
#include 

using namespace std;

int main()
{
    struct timeval tv;
    struct timezone tz;
    
    gettimeofday (&tv , &tz);
    //gettimeofday (&tv , nullptr);
    
    std::cout << "\n tv.sec = " << tv.tv_sec << ", tv.usec = " << tv.tv_usec << std::endl;
    
    std::cout << "\n tz.minuteswest = " << tz.tz_minuteswest << ", tz.tz_dsttime = " << tz.tz_dsttime << std::endl;
    return 0;
}
4. chrono库时间函数
头文件#include
函数原型std::chrono::system_clock()::成员函数
函数说明常用::now()获取当前UTC时间,用::is_steady判断是否为稳定时钟
chrono三个时间函数的区别
system_clock()系统时钟,精确到微秒。不稳定,NTP时间变化会跟着变。
steady_clock()稳定时钟,精确到纳秒。适合于记录程序耗时
high_resolution_clock()高精度时钟,精确到纳秒。相当于steady_clock的高精度版本
  • 三个函数均是c11才引入的
  • system_clock还有两个成员函数 to_time_t和from_time_t
  • system_clock和gettimeofday精度有微秒级差异,不能混用!会造成时间错乱
  • 使用实例
#include 
#include 
#include 

using namespace std;
using namespace chrono;

int main()
{
  // 是否为稳定时钟
  std::cout << "system_clock::is_steady: " << std::boolalpha << system_clock::is_steady << std::endl;
  std::cout << "steady_clock::is_steady: " << std::boolalpha << steady_clock::is_steady << std::endl;
  std::cout << "high_resolution_clock::is_steady: " << std::boolalpha << high_resolution_clock::is_steady << std::endl;
  
  auto start = system_clock::now();

  int i = 0;
  while (i < 10000)
    i++;

  duration<double> timeGap = system_clock::now() - start;
  std::cout << "timeGap: " << duration_cast<microseconds>(timeGap).count() << endl;
  
  std::time_t timeT = system_clock::to_time_t(system_clock::now()); 
  std::cout << asctime(gmtime(&timeT)) << std::endl;
  std::cout << asctime(localtime(&timeT)) << std::endl;

  duration<double> timeGap1 = system_clock::now() - system_clock::from_time_t(timeT); 
  std::cout << "timeGap: " << duration_cast<microseconds>(timeGap1).count() << std::endl;

  return 0;
}

// to_time_t: static std::time_t to_time_t( const time_point& t ) noexcept;
// from_time_t: static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;
4.2 时间转换函数
1. ctime函数
头文件#include
函数原型char* ctime(const time_t *time);
函数说明将time_t格式时间以字符串形式返回
返回值成功返回0, 失败返回-1
  • 使用实例
#include
#include
using namespace std;

int main()
{
    time_t timep;
    time(&timep);
    std::cout << ctime(&timep) << std::endl;
    return 0;
}
2. localtime函数
头文件#include
函数原型struct tm* localtime(const time_t * timep);
函数说明将time_t格式时间以tm格式返回,转换为为当地时区
返回值返回tm结构代表当地时间
  • 使用实例
#include 
#include 
#include 
using namespace std;

int main()
{
	string wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
	
	time_t timep;
	time(&timep);

	struct tm *localTime = localtime(&timep); /*取得当地时间*/

	std::cout << 1900 + localTime->tm_year << 1 + localTime->tm_mon << localTime->tm_mday;

	std::cout << " " << wday[localTime->tm_wday] << " " << localTime->tm_hour << " " << localTime->tm_min << " " << localTime->tm_sec << std::endl;

	return 0;
}

3. gmtime函数
头文件#include
函数原型struct tm* gmtime(const time_t*timep);
函数说明将tm格式时间转换为真实世界时间,中间转换使用
返回值返回tm格式时间为UTC时间
  • 使用实例
#include 
#include 
#include 
using namespace std;

int main()
{
	string wday[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
	
	time_t timep;
	time(&timep);

	struct tm *gmTime = gmtime(&timep); /*取得当地时间*/

	std::cout << 1900 + gmTime->tm_year << 1 + gmTime->tm_mon << gmTime->tm_mday;

	std::cout << " " << wday[gmTime->tm_wday] << " " << gmTime->tm_hour << " " << gmTime->tm_min << " " << gmTime->tm_sec << std::endl;

	return 0;
}
  • localtime和gmtime区别:时区。比如gmtime是10:00, 中国时间localtime就是18:00 (GMT+8)
4. asctime函数
头文件#include
函数原型char* asctime(const struct tm * timeptr);
函数说明将tm格式时间转换为当地时间,以字符串形式返回
返回值返回字符串表示当地时间
  • 使用实例
#include 
#include 
using namespace std;

int main()
{
	time_t timep;
	time(&timep);

	// gmtime将time_t格式时间转换为tm格式
	// asctime将tm格式时间转换为字符串形式
	std::cout << asctime(gmtime(&timep)) << std::endl;

	return 0;
}
5. mktime函数
头文件#include
函数原型time_t mktime(strcut tm* timeptr);/
函数说明将tm格式时间转换为time_t时间(UTC秒数)
返回值UTC时间秒数
  • 使用实例
#include 
#include 
using namespace std;

int main()
{
	time_t timep;
	time(&timep);
	std::cout << "time(): " << timep << std::endl;

	struct tm *localTime = localtime(&timep);
	timep = mktime(localTime);

	std::cout << "time() -> localTime() -> mktime(): " << timep << std::endl;
	return 0;
}
  • 执行结果
time(): 1651132717
time() -> localTime() -> mktime(): 1651132717
6. strftime函数
头文件#include
函数原型size_t strftime(char *strDest, size_t maxSize, const char *format, const struct tm *timeptr);
函数说明将tm格式时间转换为自定义时间格式。
参数strDest: 存放格式化后的字符串; maxSize: 最多可以输出的字符数; format: 格式化; timeptr: 要转换的tm格式时间
返回值UTC时间秒数
  • 使用实例
#include 
#include 
#include 
 
int main(void)
{
    char buff[70];
    struct tm tmTime;
    tmTime.tm_year = 122;
    tmTime.tm_mon = 3;
    tmTime.tm_mday = 28;
    tmTime.tm_hour = 16;
    tmTime.tm_min = 12;
    tmTime.tm_sec = 21;

    if (strftime(buff, sizeof buff, "%A %c", &tmTime)) {
		std::cout << buff << std::endl;
    } else {
		std::cout << "strftime failed" << std::endl;
    }
 
    setlocale(LC_TIME, "ja_JP");
 
    if (strftime(buff, sizeof buff, "%A %c", &tmTime)) {
		std::cout << buff << std::endl;
    } else {
		std::cout << "strftime failed" << std::endl;    
    }
    return 0;
}
4.3 时间差计算函数
difftime函数
头文件#include
函数原型double difftime(time_t, time_t)
函数说明计算两个UTC时间的差值
返回值时间差,精确到秒
  • 使用实例
#include 
#include 
#include 
using namespace std;

int main(void)
{
	time_t start, ends;
	clock_t cstart, cends;
	
	start = time(NULL);
	
	cstart = clock();
	
	sleep(3);

	ends = time(NULL);

	cends = clock();
	
	cout << "时间差:" << difftime(ends, start) << endl;
	cout << "Clock时间差:" << cends - cstart << endl;
	
	return 0;
}
4.4 线程安全的时间转换函数
  • 以下时间转换函数是线程安全的,多线程中应用对应的xxx_r函数代替xxx函数
// ctime_r: 将time_t时间转换为字符串形式
char *ctime_r(const time_t *timep, char *buf);

// localtime_r: 将time_t时间转换为当地时间,tm格式
struct tm *localtime_r(const time_t *timep, struct tm *result);

// asctime_r: 将tm使劲按转换为当地时间,字符串形式
char *asctime_r(const struct tm *tm, char *buf);

// gmtime_r: 将time_t时间转换为tm格式时间
struct tm *gmtime_r(const time_t *timep, struct tm *result);

 


参考文章:

C++时间获取函数
C++时间函数总结
线程安全的时间函数
C++时间函数实例
C++时间函数详细说明
chrono三个时间函数的区别

created by shuaixio, 2022.04.28

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/866785.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-12
下一篇 2022-05-12

发表评论

登录后才能评论

评论列表(0条)

保存