Linux 編程時間和時區

在平時編寫Linux代碼的時候,每次用到時間或者是時區都需要去查找資料,爲了以後方便,把平時用的的相關內容做個整理,方便以後查詢,畢竟好記性不如爛筆頭。

相關結構體

  • struct timeval

    /* A time value that is accurate to the nearest
     microsecond but also has a range of years.  */
    struct timeval{
    	//兩個長整型分別存放秒和微妙
    	long tv_sec;    /* Seconds.  */
     	long tv_usec;	/* Microseconds.  */
    };
    

    這個結構是系統時間的另一種表示方式,精度高,而time_t是一個長整型,表示系統時間,精確到秒。

  • struct timezone

    /* Structure crudely representing a timezone.
    This is obsolete and should never be used.  */
    struct timezone {
    	int tz_minuteswest;	/* Minutes west of GMT.  */
    	int tz_dsttime;		/* Nonzero if DST is ever in effect.  */
    };
    

    該結構體存放的是時區信息,其中tz_dsttime爲當前的狀態

  • struct tm

    /* ISO C `broken-down time' structure.  */
    struct tm{
    	int tm_sec;			  /* Seconds.	[0-60] (1 leap second) */
    	int tm_min;			  /* Minutes.	[0-59] */
    	int tm_hour;		  /* Hours.	    [0-23] */
    	int tm_mday;		  /* Day.		[1-31] */
    	int tm_mon;			  /* Month.	    [0-11] */
    	int tm_year;		  /* Year	    - 1900.  */
    	int tm_wday;		  /* Day of week. [0-6] */
    	int tm_yday;		  /* Days in year.[0-365]	*/
    	int tm_isdst;		  /* DST.		  [-1/0/1]*/
    	long int __tm_gmtoff;	/* Seconds east of UTC.  */
    	const char *__tm_zone;	/* Timezone abbreviation.  */
    };
    

    該結構存放的是具體時間信息,需要注意的是tm_year是當前年-1900,tm_mon月份是0-11所以1月是0.星期tm_wday是0-6,其中星期天爲0

相關函數

  • 時間獲取函數time()

    /* Return the current time and put it in *TIMER if TIMER is not NULL.  */
    extern time_t time (time_t *__timer) __THROW;
    

    參數time_t *__timer爲系統時間類型指針,在函數成功返回時,將系統的當前時間賦值到參數指針上。並且並返回當前系統時間,如果失敗則返回-1並設置全局變量errno

  • 字符串轉換函數ctime()asctime()

    /* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"
     that is the representation of TP in this format.  */
    extern char *asctime (const struct tm *__tp) __THROW;
    

    asctime返回一個26字節的字符串指針,它表示的是字符模式下的時間值,函數將參數struct tm *__tp所指向的結構體中的時間值轉換爲一個26字節的字符串,字符串以\0結尾,字符串模式:weekday month date hours:minutes:seconds year\n\0.

    /* Equivalent to `asctime (localtime (timer))'.  */
    extern char *ctime (const time_t *__timer) __THROW;
    

    ctime返回一個26字節的字符串指針,它表示的是字符模式下的時間值,函數將參數time_t *__timer所指向的時間值秒換爲一個26字節的字符串,字符串以\0結尾,字符串模式:weekday month date hours:minutes:seconds year\n\0.

  • 系統時間獲取設置函數gettimeofday()settimeofday()

    /* Get the current time of day and timezone information,
       putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
       Returns 0 on success, -1 on errors.
       NOTE: This form of timezone information is obsolete.
       Use the functions and variables declared in <time.h> instead.  */
    extern int gettimeofday (struct timeval *__tv,struct timezone *__tz);
    

    參數分別爲指向時間結構的指針和指向時區信息結構的指針,成功返回0,失敗返回-1.該函數會把系統時間變量賦值到結構體tv中,時區信息賦值到結構體tz中。

    /* Set the current time of day and timezone information.
    	This call is restricted to the super-user.  */
    extern int settimeofday (const struct timeval *__tv,const struct timezone *__tz)

    參數分別爲指向時間結構的指針和指向時區信息結構的指針,成功返回0,失敗返回-1.函數會把參數的時間和時區信息設置到系統。

  • 時間結構轉換函數

    /* Return the `struct tm' representation
    of *TIMER in the local timezone.  */
    extern struct tm *localtime (const time_t *__timer);
    
    /* Return the `struct tm' representation of *TIMER
    in Universal Coordinated Time (aka Greenwich Mean Time).  */
    extern struct tm *gmtime (const time_t *__timer)
    

    這兩個函數都是把一個時間戳轉化爲struct tm結構體,一個是轉爲本地時區,一個是0時區

    /* Return the `time_t' representation of TP and normalize TP.  */
    extern time_t mktime (struct tm *__tp);
    /* Another name for `mktime'.  */
    extern time_t timelocal (struct tm *__tp);
    
    /* Like `mktime', but for TP represents Universal Time, not local time.  */
    extern time_t timegm (struct tm *__tp);
    

    這三個函數都是把時間結構體轉換爲time_t時間戳,其中mktimetimelocal是一樣的的,都是轉化爲本地時間,timegm轉換爲UTC時間

Demo

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void test_ctime(void) {
    time_t local_time;
    char *str_time1, *str_time2;

    //get current local time in seconeds
    local_time = time(NULL);
    str_time1 = ctime(&local_time);
    fprintf(stderr, "%s():local time str1 is:%s\n", __FUNCTION__, str_time1);

    local_time -= 60 * 60 * 24;
    str_time2 = ctime(&local_time);
    fprintf(stderr, "%s():local time str1 is:%s\n", __FUNCTION__, str_time1);
}

static void test_asctime(void) {
    time_t local_time;
    struct tm *ptm;
    char *str_time1, *str_time2;

    //get current local time in seconeds
    local_time = time(NULL);
    //get the `struct tm' representation of *TIMER in the local timezone.
    ptm = localtime(&local_time);

    str_time1 = asctime(ptm);
    fprintf(stderr, "%s():local time str1 is:%s\n", __FUNCTION__, str_time1);

    local_time -= 60 * 60 * 24;
    ptm = localtime(&local_time);
    str_time2 = asctime(ptm);
    fprintf(stderr, "%s():local time str2 is:%s\n", __FUNCTION__, str_time2);
}

int main(int argc, char **argv) {
    test_ctime();
    test_asctime();
    return 0;
}

終端編譯程序:gcc str_main.c -o str_main
終端運行程序:./str_main
輸出:
測試結果

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

static void second_to_tm(void) {
    time_t timestamp;
    struct tm* gm_tm;
    struct tm* local_tm;

    timestamp = time(NULL);

    local_tm = localtime(&timestamp);
    fprintf(stderr, "%s():local time is:%s", __FUNCTION__, asctime(local_tm));

    //time_t to struct tm*
    gm_tm = gmtime(&timestamp);
    fprintf(stderr, "%s():gm time is:%s", __FUNCTION__, asctime(gm_tm));
}

static void tm_to_second(void) {
    struct timeval tv;
    struct tm* local_tm;
    time_t local_t, gm_t;

    if (gettimeofday(&tv, NULL) == 0) {
        local_tm = localtime(&tv.tv_sec);

        local_t = mktime(local_tm);
        fprintf(stderr, "%s():mktime time_t is:%ld\n", __FUNCTION__, local_t);

        local_t = timelocal(local_tm);
        fprintf(stderr, "%s():timelocal time_t is:%ld\n", __FUNCTION__, local_t);

        gm_t = timegm(local_tm);
        fprintf(stderr, "%s():timegm time_t is:%ld\n", __FUNCTION__, gm_t);
    }
}

int main(int argc, char** argv) {
    second_to_tm();
    tm_to_second();
    return 0;
}

終端編譯程序:gcc timezone.c -o timezone
終端運行程序:./timezone
輸出:
demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章