您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關Linux系統中如何獲取時間的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
Linux系統時間有兩種。
(1)日歷時間。該值是自協調世界時(UTC)1970年1月1日00:00:00這個特定時間以來所經過的秒數累計值。基本數據類型用time_t保存。最后通過轉換才能得到我們平時所看到的24小時制或者12小時間制的時間。
(2)進程時間。也被稱為CPU時間,用以度量進程使用的中央處理器資源。進程時間以時鐘滴答計算。
本文將給大家詳細介紹關于Linux時間的獲取和使用,下面話不多說了,來一起看看詳細的介紹吧
獲取時間戳
time()
#include <time.h> time_t time(time_t *calptr)
time返回當前時間的時間戳,也就是從世界時到現在的秒數;
time_t實際就是一個uint64_t;
calptr不為空時,時間戳也會寫入到該指針中;
調用示例:
#include <time.h> #include <iostream> #include <stdlib.h> using namespace std; int main() { time_t curTime; curTime = time(NULL); cout << curTime << endl; return 0; }
結果:
返回一串數值,如1533287924
gettimeofday()和clock_gettime()
time函數只能得到秒精度的時間,為了獲得更高精度的時間戳,需要其他函數。gettimeofday函數可以獲得微秒精度的時間戳,用結構體timeval來保存;clock_gettime函數可以獲得納秒精度的時間戳,用結構體timespec來保存。
#include <sys/time.h> int gettimeofday(struct timeval *tp, void *tzp); 因為歷史原因tzp的唯一合法值是NULL,因此調用時寫入NULL即可。 int clock_gettime(clockid_t clock_id, strcut timespec *tsp); clock_id有多個選擇,當選擇為CLOCK_REALTIME時與time的功能相似,但是時間精度更高。
兩個函數使用的結構體定義如下:
struct timeval { long tv_sec; /*秒*/ long tv_usec; /*微秒*/ }; struct timespec { time_t tv_sec; //秒 long tv_nsec; //納秒 };
調用示例:
#include <time.h> #include <sys/time.h> #include <iostream> #include <stdlib.h> using namespace std; int main() { time_t dwCurTime1; dwCurTime1 = time(NULL); struct timeval stCurTime2; gettimeofday(&stCurTime2, NULL); struct timespec stCurTime3; clock_gettime(CLOCK_REALTIME, &stCurTime3); cout << "Time1: " << dwCurTime1 << "s" << endl; cout << "Time2: " << stCurTime2.tv_sec << "s, " << stCurTime2.tv_usec << "us" << endl; cout << "Time3: " << stCurTime3.tv_sec << "s, " << stCurTime3.tv_nsec << "ns" << endl; return 0; }
結果:
編譯時要在編譯命令最后加上-lrt鏈接Real Time動態庫,如
g++ -o time2 test_time_linux_2.cpp -lrtTime1: 1533289490s
Time2: 1533289490s, 133547us
Time3: 1533289490s, 133550060ns
可視化時間
tm結構體
得到的時間戳不能直觀的展示現在的時間,為此需要使用tm結構體來表示成我們日常所見的時間,該結構體定義如下:
struct tm { int tm_sec; /*秒,正常范圍0-59, 但允許至61*/ int tm_min; /*分鐘,0-59*/ int tm_hour; /*小時, 0-23*/ int tm_mday; /*日,即一個月中的第幾天,1-31*/ int tm_mon; /*月, 從一月算起,0-11*/ 1+p->tm_mon; int tm_year; /*年, 從1900至今已經多少年*/ 1900+ p->tm_year; int tm_wday; /*星期,一周中的第幾天, 從星期日算起,0-6*/ int tm_yday; /*從今年1月1日到目前的天數,范圍0-365*/ int tm_isdst; /*日光節約時間的旗標*/ };
time_t轉成tm
gmtime 和localtime可以將time_t類型的時間戳轉為tm結構體,用法如下:
struct tm* gmtime(const time_t *timep); //將time_t表示的時間轉換為沒有經過時區轉換的UTC時間,是一個struct tm結構指針 stuct tm* localtime(const time_t *timep); //和gmtime功能類似,但是它是經過時區轉換的時間,也就是可以轉化為北京時間。
固定格式打印時間
得到tm結構體后,可以將其轉為字符串格式的日常使用的時間,或者直接從time_t進行轉換,分別可以使用以下兩個函數達到目的。不過這兩個函數只能打印固定格式的時間。
//這兩個函數已經被標記為棄用,盡量使用后面將要介紹的函數 char *asctime(const struct tm* timeptr); char *ctime(const time_t *timep);
調用示例:
#include <time.h> #include <sys/time.h> #include <iostream> #include <stdlib.h> using namespace std; int main() { time_t dwCurTime1; dwCurTime1 = time(NULL); struct tm* pTime; pTime = localtime(&dwCurTime1); char* strTime1; char* strTime2; strTime1 = asctime(pTime); strTime2 = ctime(&dwCurTime1); cout << strTime1 << endl; cout << strTime2 << endl; return 0; }
結果:
Fri Aug 3 18:24:29 2018
Fri Aug 3 18:24:29 2018
靈活安全的時間轉換函數strftime()
上述兩個函數因為可能出現緩沖區溢出的問題而被標記為棄用,因此更加安全的方法是采用strftime方法。
/* ** @buf:存儲輸出的時間 ** @maxsize:緩存區的最大字節長度 ** @format:指定輸出時間的格式 ** @tmptr:指向結構體tm的指針 */ size_t strftime(char* buf, size_t maxsize, const char *format, const struct tm *tmptr);
我們可以根據format指向字符串中格式,將timeptr中存儲的時間信息按照format指定的形式輸出到buf中,最多向緩沖區buf中存放maxsize個字符。該函數返回向buf指向的字符串中放置的字符數。
函數strftime()的操作有些類似于sprintf():識別以百分號(%)開始的格式命令集合,格式化輸出結果放在一個字符串中。格式化命令說明串 strDest中各種日期和時間信息的確切表示方法。格式串中的其他字符原樣放進串中。格式命令列在下面,它們是區分大小寫的。
%a 星期幾的簡寫
%A 星期幾的全稱
%b 月分的簡寫
%B 月份的全稱
%c 標準的日期的時間串
%C 年份的后兩位數字
%d 十進制表示的每月的第幾天
%D 月/天/年
%e 在兩字符域中,十進制表示的每月的第幾天
%F 年-月-日
%g 年份的后兩位數字,使用基于周的年
%G 年分,使用基于周的年
%h 簡寫的月份名
%H 24小時制的小時
%I 12小時制的小時
%j 十進制表示的每年的第幾天
%m 十進制表示的月份
%M 十時制表示的分鐘數
%n 新行符
%p 本地的AM或PM的等價顯示
%r 12小時的時間
%R 顯示小時和分鐘:hh:mm
%S 十進制的秒數
%t 水平制表符
%T 顯示時分秒:hh:mm:ss
%u 每周的第幾天,星期一為第一天 (值從0到6,星期一為0)
%U 第年的第幾周,把星期日做為第一天(值從0到53)
%V 每年的第幾周,使用基于周的年
%w 十進制表示的星期幾(值從0到6,星期天為0)
%W 每年的第幾周,把星期一做為第一天(值從0到53)
%x 標準的日期串
%X 標準的時間串
%y 不帶世紀的十進制年份(值從0到99)
%Y 帶世紀部分的十制年份
%z,%Z 時區名稱,如果不能得到時區名稱則返回空字符。
%% 百分號
調用示例:
#include <time.h> #include <sys/time.h> #include <iostream> #include <stdlib.h> using namespace std; int main() { time_t dwCurTime1; dwCurTime1 = time(NULL); struct tm* pTime; pTime = localtime(&dwCurTime1); char buf[100]; strftime(buf, 100, "time: %r, %a %b %d, %Y", pTime); cout << buf << endl; return 0; }
結果:
time: 08:18:12 PM, Fri Aug 03, 2018
時間函數之間的關系圖
進程時間
進程時間是進程被創建后使用CPU的時間 ,進程時間被分為以下兩個部分:
用戶CPU時間:在用戶態模式下使用CPU的時間
內核CPU時間:在內核態模式下使用CPU的時間。這是執行內核調用或其他特殊任務所需要的時間。
clock函數
clock函數提供了一個簡單的接口用于取得進程時間,它返回一個值描述進程使用的總的CPU時間(包括用戶時間和內核時間),該函數定義如下:
#include <time.h> clock_t clock(void) //if error, return -1
clock函數返回值得計量單位是CLOCKS_PER_SEC,將返回值除以這個計量單位就得到了進程時間的秒數
times函數
times函數也是一個進程時間函數,有更加具體的進程時間表示,函數定義如下:
#include <sys/times.h> clock_t times(struct tms* buf); struct tms{ clock_t tms_utime; clock_t tms_stime; clock_t tms_cutime; clock_t tms_cstime; };
times函數雖然返回類型還是clock_t,但是與clock函數返回值的計量單位不同。times函數的返回值得計量單位要通過sysconf(SC_CLK_TCK)來獲得。
Linux系統編程手冊上一個完整的使用案例如下:
#include <time.h> #include <sys/times.h> #include <unistd.h> #include <stdio.h> static void displayProcessTime(const char* msg) { struct tms t; clock_t clockTime; static long clockTick = 0; if (msg != NULL) { printf("%s\n", msg); } if (clockTick == 0) { clockTick = sysconf(_SC_CLK_TCK); if (clockTick < 0) return; } clockTime = clock(); printf("clock return %ld CLOCKS_PER_SEC (%.2f seconds)\n", (long)clockTime, (double)clockTime/CLOCKS_PER_SEC); times(&t); printf("times return user CPU = %.2f; system CPU = %.2f\n", (double)t.tms_utime / clockTick, (double)t.tms_stime / clockTick); } int main() { printf("CLOCKS_PER_SEC = %ld, sysconf(_SC_CLK_TCK) = %ld\n", (long)CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK)); displayProcessTime("start:"); for (int i = 0; i < 1000000000; ++i) { getpid(); } printf("\n"); displayProcessTime("end:"); return 0; }
Linux是一種免費使用和自由傳播的類UNIX操作系統,是一個基于POSIX的多用戶、多任務、支持多線程和多CPU的操作系統,使用Linux能運行主要的Unix工具軟件、應用程序和網絡協議。
感謝各位的閱讀!關于“Linux系統中如何獲取時間”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。