timeval及相關函數


1.結構體定義

timeval結構體在頭文件為sys/time.h中,定義如下:

struct timeval 
{
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

  該結構體以1970-01-01 00:00:00 +0000 (UTC),也就是Unix中的Epoch作為0,之后的時間都是相對於Epoch流逝的秒和毫秒數。其中tv_sec是秒,tv_usec微秒(microsecond ),即10-6秒,而不是毫秒(millisecond),10-3秒。

 

2. 關聯函數

gettimeofday

位於頭文件sys/time.h中,函數聲明如下:

int gettimeofday(struct timeval *tv, struct timezone *tz);

  用於獲取調用該代碼時,距離Epoch的時間。

第一個參數不用多說,第二個參數也是結構體,定義如下:

struct timezone 
{
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction */
};

 根據Linux的手冊中關於函數gettimeofday的描述(man gettimeofday):

The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL

這種使用方式是過時的,該處通常提供NULL作為參數。

測試代碼:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>

int main()
{
    struct timeval tv;int i;
    
    for(i=0;i<5;i++)
    {
        gettimeofday(&tv, NULL);
        printf("%ld.%06ld\n", tv.tv_sec, tv.tv_usec);
        sleep(1);    
    }
    return 0;
}

運行效果如下(和運行時間有關):

1610953256.769513
1610953257.769901
1610953258.770804
1610953259.771444
1610953260.771719

可以看到,並不是非常精確的1秒延時,多次測試發現延時都會滯后一點不過在一般的應用場合是足夠了,例如,我們可以兩次調用這個函數,測試一段代碼執行所消耗的時間等。

另外一個與之相關的函數是settimeofday,看名字就知道是和gettimeofday對應的,這里就不去展開討論了。

3. 同日期之間的轉換

在獲取了相對於Epoch的時間以后,相應的日期也就可以確定了,這個時候就要用到time.h中的結構體struct tm了。結構體定義如下:

struct tm 
{
  int tm_sec; /* Seconds (0-60) */   int tm_min; /* Minutes (0-59) */   int tm_hour; /* Hours (0-23) */   int tm_mday; /* Day of the month (1-31) */   int tm_mon; /* Month (0-11) */   int tm_year; /* Year - 1900 */   int tm_wday; /* Day of the week (0-6, Sunday = 0) */   int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */   int tm_isdst; /* Daylight saving time */ };

與之相關的幾個函數分別是gmtime\localtime、mktime。

先說說將時間戳轉換為日期的函數gmtime和localtime,前者是GMT時間,而后者是本地時間,例如現在北京時間是下午16點,則GMT時間實際上是當日的上午8點(我們在東八區,記作GMT+8)。

gmtime定義如下:

struct tm *gmtime(const time_t *timep);

接收一個time_t*的指針,然后將其轉換為了代表gmt時間的結構體t指針,需要年月日時分秒等,都可以從這個返回的tm結構體中獲取,測試代碼如下。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>

int main()
{
    struct timeval tv;    
    struct tm* st;
    gettimeofday(&tv, NULL);    
    printf("%ld.%06ld\n", tv.tv_sec, tv.tv_usec);
    st=gmtime(&tv.tv_sec);
    printf("%02d:%02d:%02d\n",st->tm_hour,st->tm_min,st->tm_sec);
    return 0;
}

這將顯示當前的時間,由於使用的是GMT時間,因此,比北京時間慢了8小時,如果使用localtime而不是gmtime的話,則和北京時間相同。

反過來,如果我們向知道某個日期所對應的相對Epoch時間是多少,則可以使用mktime函數,這個函數原型如下:

time_t mktime(struct tm *tm);

就是將tm結構體指針轉換為time_t,測試代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>

int main()
{
    time_t tt;
    struct tm st;
    st.tm_year=121;//year=1900+121=2021
    st.tm_mon=0;//for Jaunary
    st.tm_mday=18;
    st.tm_hour=7;
    st.tm_min=39;
    st.tm_sec=34;
    tt=mktime(&st);
    printf("%ld\n",tt);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM