1 兩種時間
linux提供了兩種時間:
(1)日歷時間。該值是自 協(xié)調(diào)世界時(Coordinated Universal Time, UTC)1970年1月1日00::00::00這個特定時間以來所經(jīng)過的秒數(shù)累計值。(早期稱UTC為格林尼治標(biāo)準(zhǔn)時間)
系統(tǒng)基本數(shù)據(jù)類型time_t用于保存這種時間值。
(2)進(jìn)程時間。也被成為CPU時間,用以度量進(jìn)程使用的中央處理器資源。進(jìn)程時間以時鐘滴答計算。調(diào)用sysconf函數(shù)可以獲得每秒得時間滴答數(shù)。
系統(tǒng)基本數(shù)據(jù)類型clock_t用于保存這種時間值。
為了度量一個進(jìn)程的執(zhí)行時間,linux系統(tǒng)維護(hù)了3個進(jìn)程時間值:
(1)時鐘時間; //進(jìn)程運(yùn)行的時間總量
(2)用戶CPU時間; //執(zhí)行用戶指令所用時間(用戶態(tài)時間)
(3)系統(tǒng)CPU時間; //執(zhí)行內(nèi)核程序所用時間(內(nèi)核態(tài)時間)
用戶cpu時間和系統(tǒng)cpu時間總和稱為cpu時間。
執(zhí)行time命令,可以取得任一進(jìn)程的時鐘時間、用戶時間和系統(tǒng)時間。
2 獲取時間相關(guān)函數(shù)
2.1 獲取秒級時間函數(shù)
#include time_t time(time_t *timer);//通過函數(shù)返回值或者timer 變量均可以獲取到當(dāng)前時間
time_t實(shí)際上是一個長整型,表示UTC時間(1970年1月1日0時0分0秒,Linux系統(tǒng)的Epoch時間)到當(dāng)前系統(tǒng)時間的秒數(shù)級時間差
2.2 獲取微秒級時間函數(shù)
#include #include struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */};struct timezone{ int tz_minuteswest; /*miniutes west of Greenwich*/ int tz_dsttime; /*type of DST correction*/};//函數(shù)執(zhí)行成功返回0,失敗返回-1. 其中timezone 是時區(qū)相關(guān)的結(jié)構(gòu)體int gettimeofday(struct timeval *tv, struct timezone *tz);//用來設(shè)置指定的時間和時區(qū)信息int settimeofday(const struct timeval *tv, const struct timezone *gz);
2.3 獲取納秒級時間函數(shù)
#include /*其中clk_id 用來指定對應(yīng)的時鐘類型,不同的類型可以用來獲取不同的時間值,具體有四種:CLOCK_REALTIME: 系統(tǒng)實(shí)時時間,從UTC開始計時,若時間被用戶更改計數(shù)時間相應(yīng)改變;CLOCK_MONOTONIC:從系統(tǒng)啟動開始計時,即使用戶更改時間也沒有影響;CLOCK_PROCESS_CPUTIME_ID:本進(jìn)程開始到執(zhí)行到當(dāng)前程序系統(tǒng)CPU花費(fèi)的時間;CLOCK_THREAD_CPUTIME_ID:本線程開始到執(zhí)行到當(dāng)前程序系統(tǒng)CPU花費(fèi)的時間*/struct timespec{ time_t tv_sec; //s long tv_nsec; //ns};int clock_gettime(clockid_t clk_id, struct timespec* tp);
當(dāng)時鐘類型設(shè)置為CLOCK_REALTIME時,clock_gettime函數(shù)提供了與time函數(shù)類似的功能,不過在系統(tǒng)支持高精度值得情況下,clock_gettime可能比time函數(shù)得到更高精度的時間值。
舉例:若想獲取從系統(tǒng)啟動開始計時,即使用戶更改時間也沒有影響的時間,單位微秒,如下:
int64_t get_time_point_monotonic() { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec * 1000000L + ts.tv_nsec / 1000;}
3 轉(zhuǎn)換時間相關(guān)函數(shù)
3.1 將time_t轉(zhuǎn)換為結(jié)構(gòu)體struct tm
struct tm包含年月日等非常詳細(xì)的域,如下所示:
#include struct tm{ int tm_sec; //秒 int tm_min; //分 int tm_hour; //時;取值區(qū)間為[0, 23] int tm_mday; //日;取值區(qū)間為[1, 31] int tm_mon; //月份;取值區(qū)間為[0, 11]; 0表示1月份依次遞增到12月份 int tm_year; //年份;其值為1900年至今年數(shù) int tm_wday; //星期;0代表星期天,1代表星期1,以此類推 int tm_yday; //日期;0代表1月1日 int tm_isdst; //夏令時標(biāo)識符;使用夏令時為正,不使用t為0,不確定時為負(fù)*/};
將time_t轉(zhuǎn)換成struct tm結(jié)構(gòu)體常用的函數(shù)如下:
#include struct tm* gmtime(const time_t* timep);struct tm* localtime(const time_t* timep);
gmtime()轉(zhuǎn)換的結(jié)果是UTC對應(yīng)的信息,而localtime() 函數(shù)轉(zhuǎn)換的結(jié)果是當(dāng)前所在時區(qū)的信息。
3.2 將time_t轉(zhuǎn)換成我們習(xí)慣性使用的時間和日期字符串
對應(yīng)轉(zhuǎn)換函數(shù)如下:
#include char* ctime(time_t* timep);
3.3 將struct tm 轉(zhuǎn)換成 time_t對應(yīng)函數(shù)如下:
#include time_t mktime(struct tm *p_tm);
3.4 將struct tm轉(zhuǎn)換成我們習(xí)慣性使用的時間和日期字符串對應(yīng)函數(shù)如下:
#include char *asctime(const struct tm *p_tm); //習(xí)慣性字符串 Thu Dec 9 07:13:35 2021
3.5 將時間字符串轉(zhuǎn)換成 struct tm格式
/**************************************** description: 將struct tm 按照指定的format格式轉(zhuǎn)化成字符串** parameter:** *s : 需要被轉(zhuǎn)換的時間字符串** *format:時間字符串的格式** *tm:轉(zhuǎn)換后的tm時間**************************************/char *strptime(const char *s, const char *format, struct tm *tm);
3.6 將struct tm 按照指定的format格式轉(zhuǎn)化成字符串
/**************************************** description: 將struct tm 按照指定的format格式轉(zhuǎn)化成字符串** parameter:** *s : 生成的時間字符串** max: 字符串最大字符數(shù)(即最大可生成的字符數(shù)量)** *format:生成的字符串格式** *tm:需要被轉(zhuǎn)換的tm時間**************************************/size_t strftime(char *s, size_t max, const char *format,const struct tm *tm);