linux下常用時間函數

在linux下編程,有一些常用的時間函數,下面做一個總結梳理。

1、time

SYNOPSIS
       #include <time.h>

       time_t time(time_t *t);

DESCRIPTION
       time() returns the time since the Epoch (00:00:00 UTC, January 1, 1970), mea-
       sured in seconds.

       If t is non-NULL, the return value is also stored in the memory pointed to by
       t.

先說一下,time_t類型是一個有符號整數,是32位系統下,就是32位有符號數,在64位系統下,就是64位有符號數。那麼time函數返回的是自從UTC時間1970年1月1日 00:00:00到現在經過的秒數,如果32位有符號數存儲這個值,那麼在2038年這個值將溢出,無法存儲這麼大的數了。

這個函數傳進去一個time_t指針,會將時間寫入這個傳入的內存,同時time也返回這個值,總感覺有點多餘,要麼用返回值,要麼用指針。

int now = time(NULL); // 常用的形式

2、localtime

 struct tm *localtime(const time_t *timep);
 struct tm *localtime_r(const time_t *timep, struct tm *result);

 struct tm {
               int tm_sec;         /* seconds */
               int tm_min;         /* minutes */
               int tm_hour;        /* hours */
               int tm_mday;        /* day of the month */
               int tm_mon;         /* month */
               int tm_year;        /* year */
               int tm_wday;        /* day of the week */
               int tm_yday;        /* day in the year */
               int tm_isdst;       /* daylight saving time */
           };
/*
The members of the tm structure are:

       tm_sec    The  number of seconds after the minute, normally in the range 0 to
                 59, but can be up to 60 to allow for leap seconds.

       tm_min    The number of minutes after the hour, in the range 0 to 59.

       tm_hour   The number of hours past midnight, in the range 0 to 23.

       tm_mday   The day of the month, in the range 1 to 31.

       tm_mon    The number of months since January, in the range 0 to 11.

       tm_year   The number of years since 1900.
       tm_wday   The number of days since Sunday, in the range 0 to 6.

       tm_yday   The number of days since January 1, in the range 0 to 365.

       tm_isdst  A flag that indicates whether daylight saving time is in effect  at
                 the  time described.  The value is positive if daylight saving time
                 is in effect, zero if it is not, and negative if the information is
                 not available.

*/

這兩個函數是將time_t的時間戳轉化爲本地且容易閱讀的時間,關鍵是tm結構體,註釋已經很清楚了。這兩個函數的區別是前者是線程不安全的函數,後者是線程函數函數。你看第一個函數,平白無故的返回一個指針,很少看到這種情況,其實這個指針指向的是一個函數內部靜態分配的結構體,有可能被其他線程重寫,所以是不安全的,儘量用第二個。

3、gettimeofday

#include <sys/time.h>

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

struct timeval {
               time_t      tv_sec;     /* seconds */
               suseconds_t tv_usec;    /* microseconds */
           };
 struct timezone {
               int tz_minuteswest;     /* minutes west of Greenwich */
               int tz_dsttime;         /* type of DST correction */
           };

這個函數也可以得到當前的時間,而且可以達到微秒級別,由第一個參數tv指針傳出,第二個參數tz已經廢棄,傳入NULL即可。

timeval結構體,保存秒數和微秒數,也是從UTC時間1970年1月1日 00:00:00算起的。

測試程序:

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

int main ()
{
  struct  timeval tv;
  gettimeofday(&tv,NULL);
  printf("second=%d\n", tv.tv_sec);
  printf("microseconds=%d\n", tv.tv_usec);
  printf("time=%d\n", time(0));
  return 0;
}
輸出:
[KentZhang@LOCAL-192-168-97-2 ]$ ./a.out 
second=1543334965
microseconds=963832
time=1543334965

4、clock_gettime

#include <time.h>

int clock_gettime(clockid_t clk_id, struct timespec *tp);
/*
clk_id 有以下五種取值,我只用過前2個,後面3個待研究。
CLOCK_REALTIME // 獲取實時時間,類似time()
              System-wide real-time clock.  Setting this clock requires  appropriate
              privileges.
CLOCK_MONOTONIC // 獲取系統從啓動到現在經歷的時間
              Clock  that  cannot  be  set  and represents monotonic time since some
              unspecified starting point.
CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
              Similar to CLOCK_MONOTONIC, but provides access  to  a  raw  hardware-
              based time that is not subject to NTP adjustments.
CLOCK_PROCESS_CPUTIME_ID
              High-resolution per-process timer from the CPU.
CLOCK_THREAD_CPUTIME_ID
              Thread-specific CPU-time clock.
*/    

// 傳出參數的結構體,保存秒和納秒    
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};

據說這個函數是獲取系統的時鐘時間,和CPU的時鐘有關係,所以精度才比較高。

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