【c/c++】linux时间获取与时间转换函数总结
1. 序言
程序中常需要记录时间戳或者计算模块耗时,在此对时间函数及应用场景做一个总结
2. 有哪些函数
获取时间
clock, time, gettimeofday, chrono库时间函数
时间格式转换
ctime, localtime, gmtime, asctime, mktime, strftime
其他
计算时间差:difftime
时间转换线程安全函数:ctime_r, localtime_r, asctime_r, gmtime_r
3. 选用场景
- 获取时间的函数
- 时间转换函数
- 其他时间函数
ctime/asctime两者传入的参数结构不同,见4. 详细解析
4. 详细解析
4.1 时间获取函数
使用实例
#include <iostream>
#include <iomanip>
#include <chrono>
#include <time.h> // 或 #include <ctime>
#include <thread>
// 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
使用实列
#include <time.h>
#include <iostream>
using namespace std;
int main()
time_t seconds = time((time_t*)NULL);
std::cout << seconds << std::endl;
return 0;
# 编译运行
g++ -o main main.cpp
# 编译运行
g++ -o main main.cpp
使用实例
#include<sys/time.h>
#include<unistd.h>
#include <iostream>
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;
}
- 三个函数均是c11才引入的
- system_clock还有两个成员函数 to_time_t和from_time_t
- system_clock和gettimeofday精度有微秒级差异,不能混用!会造成时间错乱
- 使用实例
#include <iostream>
#include <chrono>
#include <time.h>
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)
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 时间转换函数
使用实例
#include<time.h>
#include<iostream>
using namespace std;
int main()
time_t timep;
time(&timep);
std::cout << ctime(&timep) << std::endl;
return 0;
}
使用实例
#include <time.h>
#include <iostream>
#include <string>
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;
}
使用实例
#include <time.h>
#include <iostream>
#include <string>
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)
使用实例
#include <time.h>
#include <iostream>
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;
}
使用实例
#include <time.h>
#include <iostream>
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
使用实例
#include <iostream>
#include <time.h>
#include <locale.h>
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 时间差计算函数
使用实例
#include <iostream>
#include <time.h>
#include <unistd.h>
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);