溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++時(shí)間函數(shù)怎么使用

發(fā)布時(shí)間:2022-10-31 09:57:19 來(lái)源:億速云 閱讀:134 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“C++時(shí)間函數(shù)怎么使用”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“C++時(shí)間函數(shù)怎么使用”文章能幫助大家解決問(wèn)題。

    一、 時(shí)間概念

    格林威治時(shí)間GMT(Greenwich Mean Time)

    格林威治皇家天文臺(tái)為了海上霸權(quán)的擴(kuò)張計(jì)劃,在十七世紀(jì)就開(kāi)始進(jìn)行天體觀測(cè)。為了天文觀測(cè),選擇了穿過(guò)英國(guó)倫敦格林威治天文臺(tái)子午儀中心的一條經(jīng)線作為零度參考線,這條線,簡(jiǎn)稱格林威治子午線。

    1884年10月召開(kāi)了一個(gè)國(guó)際子午線會(huì)議,該會(huì)議將格林威治子午線設(shè)定為本初子午線,并將格林威治平時(shí) (GMT, Greenwich Mean Time) 作為世界時(shí)間標(biāo)準(zhǔn)(UT, Universal Time)。由此也確定了全球24小時(shí)自然時(shí)區(qū)的劃分,所有時(shí)區(qū)都以和 GMT 之間的偏移量做為參考。

    1972年之前,格林威治時(shí)間(GMT)一直是世界時(shí)間的標(biāo)準(zhǔn)。1972年之后,GMT 不再是一個(gè)時(shí)間標(biāo)準(zhǔn)了。

    XP系統(tǒng)中,默認(rèn)時(shí)間格式是GMT。

    目前UTC與GMT 相差為0.9秒,故二者可以基本視為一致。

    原子時(shí)間

    1967年,人們利用銫原子振蕩周期極為規(guī)律的特性,研制出了高精度的原子時(shí)鐘,將銫原子能級(jí)躍遷輻射9192631770周所經(jīng)歷的時(shí)間定為1s?,F(xiàn)在用的時(shí)間就是1971年10月定義的國(guó)際原子時(shí),是通過(guò)世界上大約200多臺(tái)原子鐘進(jìn)行對(duì)比后,再由國(guó)際度量衡局時(shí)間所進(jìn)行數(shù)據(jù)處理,得出的統(tǒng)一的原子時(shí),簡(jiǎn)稱TAI。

    世界協(xié)調(diào)時(shí)

    又稱世界統(tǒng)一時(shí)間、世界標(biāo)準(zhǔn)時(shí)間。UTC是現(xiàn)在全球通用的時(shí)間標(biāo)準(zhǔn),全球各地都同意將各自的時(shí)間進(jìn)行同步協(xié)調(diào)。UTC 時(shí)間是經(jīng)過(guò)平均太陽(yáng)時(shí)(以格林威治時(shí)間GMT為準(zhǔn))、地軸運(yùn)動(dòng)修正后的新時(shí)標(biāo)以及以秒為單位的國(guó)際原子時(shí)所綜合精算而成。

    UTC 構(gòu)成:

    原子時(shí)間(TAI):

    結(jié)合了全球400個(gè)所有的原子鐘而得到的時(shí)間,它決定了我們每個(gè)人的鐘表中,時(shí)間流動(dòng)的速度。

    世界時(shí)間(UT, Universal Time):

    也稱天文時(shí)間,或太陽(yáng)時(shí),他的依據(jù)是地球的自轉(zhuǎn),我們用它來(lái)確定多少原子時(shí),對(duì)應(yīng)于一個(gè)地球日的時(shí)間長(zhǎng)度。

    格式: YYYY-MM-DDThh:mm:ssZ

    協(xié)調(diào)世界時(shí)不與任何地區(qū)位置相關(guān),也不代表此刻某地的時(shí)間,所以在說(shuō)明某地時(shí)間時(shí)要加上時(shí)區(qū)。也就是說(shuō)GMT并不等于UTC,而是等于UTC+0,只是格林尼治剛好在0時(shí)區(qū)上。GMT = UTC+0。

    本地時(shí)間

    在日常生活中所使用的時(shí)間我們通常稱之為本地時(shí)間。這個(gè)時(shí)間等于我們所在(或者所使用)時(shí)區(qū)內(nèi)的當(dāng)?shù)貢r(shí)間,它由與世界標(biāo)準(zhǔn)時(shí)間(UTC)之間的偏移量來(lái)定義。這個(gè)偏移量可以表示為 UTC- 或 UTC+,后面接上偏移的小時(shí)和分鐘數(shù)。

    GMT是前世界標(biāo)準(zhǔn)時(shí),UTC是現(xiàn)世界標(biāo)準(zhǔn)時(shí)。

    UTC 比 GMT更精準(zhǔn),以原子時(shí)計(jì)時(shí),適應(yīng)現(xiàn)代社會(huì)的精確計(jì)時(shí)。

    但在不需要精確到秒的情況下,二者可以視為等同。

    每年格林尼治天文臺(tái)會(huì)發(fā)調(diào)時(shí)信息,基于UTC。

    二、Linux-c時(shí)間的存儲(chǔ)方式

    1. time_t

    一個(gè)整型,存儲(chǔ)從1970-1-1 00:00:00年到現(xiàn)在UTC+0經(jīng)過(guò)了多少秒,進(jìn)一步的,struct timeval可精確到微秒。

    2. struct tm

    用一個(gè)結(jié)構(gòu)來(lái)分別存儲(chǔ)年月日時(shí)分秒。

    	struct tm
    	{
    	    int tm_sec;  /*秒,正常范圍0-59, 但允許至61*/
    	    int tm_min;  /*分鐘,0-59*/
    	    int tm_hour; /*小時(shí), 0-23*/
    	    int tm_mday; /*日,即一個(gè)月中的第幾天,1-31*/
    	    int tm_mon;  /*月, 從一月算起,0-11*/  1+p->tm_mon;
    	    int tm_year;  /*年, 從1900至今已經(jīng)多少年*/  1900+ p->tm_year;
    	    int tm_wday; /*星期,一周中的第幾天, 從星期日算起,0-6*/
    	    int tm_yday; /*從今年1月1日到目前的天數(shù),范圍0-365*/
    	    int tm_isdst; /*日光節(jié)約時(shí)間的旗標(biāo)*/
    	};
    特別注意,年份是從1900年起至今多少年,而不是直接存儲(chǔ)如2022年。月份從0開(kāi)始的,0表示一月,星期也是從0開(kāi)始的, 0表示星期日,1表示星期一。

    三、 常用函數(shù)

    #include <time.h>

    #include <sys/time.h>

    time_t time(time_t* t);

    取得從1970-1-1 00:00:00至今(UTC+0)的秒數(shù),注意并不是至本地時(shí)間的秒數(shù)。該時(shí)間戳為GMT時(shí)間,即時(shí)區(qū)為0。

    time()總是返回的是當(dāng)前格林威治時(shí)間,不論系統(tǒng)/程序采用的哪個(gè)時(shí)區(qū)。所以使用time_t時(shí)候,讓time_t上的存儲(chǔ)值總是描述格林威治時(shí)間。

        time_t tm = time(nullptr);//取得從1970-1-1 00:00:00至今(UTC+0)的秒數(shù)
        //或
        time(&tm0);

    struct tm* gmtime(const time_t* timep);

    將time_t表示的時(shí)間戳轉(zhuǎn)換為沒(méi)有經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間,是一個(gè)struct tm結(jié)構(gòu)指針。

        struct tm *tmStamp = nullptr;
        time_t tmSec = time(nullptr); 
        tmStamp = gmtime(&tmSec);   //返回沒(méi)有經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間 struct tm結(jié)構(gòu)

    struct tm* localtime(const time_t* timep);

    將time_t表示的時(shí)間戳轉(zhuǎn)換換成經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的時(shí)間。使用time_t格林威治時(shí)間+時(shí)區(qū)偏差,生成tm結(jié)構(gòu)

        struct tm *tmStamp = nullptr;
        time_t tmSec;
        time(&tmSec); //取得從1970年1月1日至今的秒數(shù)
        tmStamp = localtime(&tmSec); //返回經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的時(shí)間,***注意本函數(shù)可能會(huì)修改時(shí)間秒的值***

    time_t mktime(struct tm* timeptr);

    將struct tm 結(jié)構(gòu)的時(shí)間轉(zhuǎn)換為從1970-1-1年至今的秒數(shù)。

    mktime考慮了時(shí)區(qū),輸入的值總是要求【localtime-tm】結(jié)構(gòu)-當(dāng)前時(shí)區(qū)時(shí)間,輸出值格林威治時(shí)間;

    char asctime(const struct tm timeptr);

    將struct tm結(jié)構(gòu)中的信息轉(zhuǎn)換為真實(shí)世界的時(shí)間(不經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間),以字符串的形式顯示。

        time_t timeSec;
        time(&timeSec); /*獲取time_t類型的當(dāng)前時(shí)間*/
        /*用gmtime將time_t類型的時(shí)間轉(zhuǎn)換為struct tm類型的時(shí)間,按沒(méi)有經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間
          然后再用asctime轉(zhuǎn)換為我們常見(jiàn)的格式 ,形式:Mon Oct 24 11:41:17 2022
        */
        printf("%s", asctime(gmtime(&timeSec))); //沒(méi)有經(jīng)過(guò)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間

    char ctime(const time_t timep);

    將 time_t時(shí)間秒表示的時(shí)間轉(zhuǎn)換為真實(shí)世界的時(shí)間(經(jīng)時(shí)區(qū)轉(zhuǎn)換的UTC時(shí)間),以字符串顯示。

    ctime考慮了時(shí)區(qū),輸入值要求time_t是格林威治時(shí)間,輸出來(lái)的值總是用來(lái)描述當(dāng)?shù)貢r(shí)間。

    // 形式:Mon Oct 24 11:41:17 2022
    ``
    ## 7. gettimeofday(&tmval,&zone); // for linux 
    返回當(dāng)前距離1970年的秒數(shù)和微妙數(shù),后面的tz是時(shí)區(qū),一般不用傳NULL。
    ```c
    	struct timezone zone;
        struct timeval tmval;
        gettimeofday(&tmval,&zone); // for linux

    double difftime(time_t time1, time_t time2);

    返回兩個(gè)時(shí)間秒相差的秒數(shù)。

    ctime返回的是靜態(tài)變量地址;更要注意gmtime與localtime返回的靜態(tài)變量地址是同一個(gè),后調(diào)用的會(huì)覆蓋上次調(diào)用的值;

    tm結(jié)構(gòu)存儲(chǔ)值有時(shí)用來(lái)描述格林威治時(shí)間gmtime,有時(shí)用來(lái)描述當(dāng)?shù)貢r(shí)間localtime-當(dāng)前時(shí)區(qū)時(shí)間。

    四、 時(shí)間格式化

    size_t strftime(char *str, size_t count, const char *format, const struct tm *tm)

    函數(shù)原型
    #include <time.h>
    size_t strftime(char *str, size_t count, const char *format, const struct tm *tm);
    參數(shù)說(shuō)明
      str, 表示返回的時(shí)間字符串
      count, 要寫入的字節(jié)的最大數(shù)量
      format, 格式字符串由零個(gè)或多個(gè)轉(zhuǎn)換符和普通字符(除%)
      tm, 輸入時(shí)間
    返回值
      如果包含終止的空字符在內(nèi)的結(jié)果字符的總數(shù)不大于count,則函數(shù)strftime返回字符數(shù),這些字符被放到s指向的數(shù)組中但不包含終止的空字符。否則,函數(shù)返回零,且數(shù)組的內(nèi)容不確定。

    一個(gè)常規(guī)用法

    	char* format = "%Y-%m-%d %H:%M:%S";
        char strTime[100];
        strftime(strTime, sizeof(strTime), format, tmTime);//2022-10-07 20:46:01

    五、計(jì)時(shí)器-時(shí)間段

    #include <time.h>
    #include <iostream>
    using namespace std;
    clock_t start = clock();
    // do something...
    clock_t end   = clock();
    cout << "花費(fèi)了" << (double)(end - start) / CLOCKS_PER_SEC << "秒" << endl;

    可精確到毫秒

    六、chrono

    C++ 11 標(biāo)準(zhǔn)庫(kù)引入了chrono庫(kù)。利用該庫(kù)可以做時(shí)間運(yùn)算和換算。

    一個(gè)性能統(tǒng)計(jì)用法

    #include <chrono>   
    using namespace std;
    using namespace chrono;
    auto start = system_clock::now();
    // do something...
    auto end   = system_clock::now();
    auto duration = duration_cast<microseconds>(end - start);
    cout <<  "花費(fèi)了" 
         << double(duration.count()) * microseconds::period::num / microseconds::period::den 
         << "秒" << endl;
    //精確到微妙

    關(guān)于“C++時(shí)間函數(shù)怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    c++
    AI