APUE學習筆記——6.10 時間與時間例程 time_t



       Unix提供的最基本的時間服務室日曆時間(紀元時間),也就是計算1970年1月1日0時0分0秒到當前的秒數。該秒數用time_t表示。
typedef long     time_t;    /* 時間值time_t 爲長整型的別名*/

一、獲取/設置時間

1.1 time和time_t

函數time()能夠用於獲取當前日曆時間
#include <time.h>
time_t time(time_t *calptr);
                                    Returns: value of time if OK,−1 on error
       當前時間值(即 1970年1月1日0時0分0秒到如今的秒數 )保存給calptr指針指向的地址,也做爲返回值。

1.2 指定時鐘類型

Unix提供指定時鐘類型來獲取/設置時間的方法。
 #include <time.h>
       int clock_getres(clockid_t clk_id, struct timespec *res);
       int clock_gettime(clockid_t clk_id, struct timespec *tp);
       int clock_settime(clockid_t clk_id, const struct timespec *tp);
                                  Link with -lrt.編譯時使用連接庫lrt
clock_gettime() 和clock_settime(); 函數提供了納秒級別的時間,而且會根據clk_id的時間類型進行取值。
clock_getres 用於獲取時間的分辨率。   clock_gettime() 和clock_settime()使用的時間必須是時間分辨率的整數倍,不是整數倍也要切割成整數倍。
clockid_tclk_id 用於指定計時時鐘的類型,有如下選項:
CLOCK_REALTIME:系統實時時間,使用此選項時功能至關於time(),若是系統時間被用戶修改過,則對應的時間相應改變
CLOCK_MONOTONIC:從系統啓動這一刻起開始計時,不受系統時間被用戶改變的影響
CLOCK_PROCESS_CPUTIME_ID:本進程運行的CPU時間
CLOCK_THREAD_CPUTIME_ID:本線程運行的CPU時間

 struct timespec {
               time_t   tv_sec;        /* seconds */
               long     tv_nsec;       /* nanoseconds */
           };

1.3 gettimeofday()與settimeofday()

Unix/Linux提供了微秒級別獲取和設置時間的函數 gettimeofday()與settimeofday(),但根據man手冊的描述,這兩個函數已通過時,此處不作介紹。僅列出原型(這兩個函數編譯須要glibc的支持)
       #include <sys/time.h>
       int gettimeofday(struct timeval *tv, struct timezone *tz);
       int settimeofday(const struct timeval *tv, const struct timezone *tz);

二、時間格式轉換

    咱們使用time()等函數獲取的時間是一個time_t獲取的重新紀元開始到當前所通過的秒數,是一個整數值。(calender time)
    咱們不少狀況下須要將其轉換成咱們可讀的,向時分秒這樣的時間(broken down time)。這就須要進行轉化。
    時間轉換圖如 Figure6.9 所示


    咱們使用struct tm來保存broken-down  time
struct tm { /* a broken-down time */
    int  tm_sec;     // 秒 【0~60】 60存在的緣由是閏秒的存在
    int  tm_min;     //分
    int  tm_hour;    //時
    int  tm_mday;    //日
    int  tm_mon;     //月
    int  tm_year;    //年   結構中記錄的是從1900至今的年數
    int  tm_wday;    //星期幾  【0~6】
    int  tm_yday;    // 一年中第幾天
    int  tm_isdst;   // 夏時制標誌
};

夏時制,夏時令(Daylight Saving Time:DST),又稱「日光節約時制」和「夏令時間」,是一種爲節約能源而人爲規定地方時間的制度,在這一制度實行期間所採用的統一時間稱爲「夏令時間」。通常在天亮早的夏季人爲將時間提早一小時,能夠令人早起早睡,減小照明量,以充分利用光照資源,從而節約照明用電。
    Unix提供了時間格式轉換的函數

2.1 time_t與struct tm相互轉化


time_t轉化成struct tm
#include <time.h>
struct tm *gmtime(const time_t *calptr);
struct tm *localtime(const time_t *calptr);
                               Both return: pointer to broken-down time,NULLon error
gmtime 轉換成國際標準時間
localtime轉換成本地時間(考慮到本地時區和夏時制標誌)
struct tm轉化成time_t
#include <time.h>
time_t mktime(struct tm *tmptr);
                   Returns: calendar time if OK,−1 on error
example:
#include<stdio.h>
#include <time.h>
#include<sys/time.h>
int main(void)
{
        time_t calptr;
        if (time(&calptr) == -1)
        {
                printf("Error: time() failed!\n");
                exit(0);
        }
        printf("Time(time_t) now is: %d\n",(long) calptr);
        /*
         *      轉換成可讀到時間
         */
        struct tm *gmptr;               //國際標準時間
        struct tm *localptr;            //本地時間
 
/*      轉換成國際標準時間      */
        printf("\n\n ----------gm time--------------\n");
        if (NULL == (gmptr = gmtime(&calptr)))
        {
                printf("Error: can't convert time_t to struct tm by gmtime()!\n");
                exit(0);
        }
        printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", gmptr->tm_year, gmptr->tm_mon, gmptr->tm_mday, gmptr->tm_wday);
        printf("Hour:%d,\tMin:%d,\t,sec:%d\n", gmptr->tm_hour, gmptr->tm_min, gmptr->tm_sec);
        /*      轉換成本地標準時間      */
        printf("\n\n ----------local time--------------\n");
        if (NULL == (localptr = localtime(&calptr)))
        {
                printf("Error: can't convert time_t to struct tm by localtime()!\n");
                exit(0);
        }
        printf("year:%d,\tMonth:%d,\tDay:%d,\tWeek:%d\n", localptr->tm_year, localptr->tm_mon, localptr->tm_mday, localptr->tm_wday);
        printf("Hour:%d,\tMin:%d,\t,sec:%d\n", localptr->tm_hour, localptr->tm_min, localptr->tm_sec);
        return 0;
}


運行結果:
windeal@ubuntu:~/Windeal/apue$ ./exe 
Time(time_t) now is: 1409207607
 ----------gm time--------------
year:114,	Month:7,	Day:28,	Week:4
Hour:6,	Min:33,	,sec:27
 ----------local time--------------
year:114,	Month:7,	Day:28,	Week:4
Hour:14,	Min:33,	,sec:27


東八區,快了8個小時

2.2 轉換成格式化字符串

#include <time.h>
size_t strftime(char *restrict buf,size_t maxsize,
                 const char *restrict format,
                 const struct tm *restrict tmptr);
size_t strftime_l(char *restrict buf,size_t maxsize,
                  const char *restrict format,
                  const struct tm *restrict tmptr,locale_t locale);
                ——Both return: number of characters stored in array if room, 0 otherwise


Example:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int
main(void)
{
        time_t t;
        struct tm *tmp;
        char buf1[16];
        char buf2[64];
        time(&t);
        tmp = localtime(&t);
        if (strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0)
                printf("buffer length 16 is too small\n");
        else
                printf("%s\n", buf1);
        
        if (strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0)
                printf("buffer length 64 is too small\n");
        else
                printf("%s\n", buf2);
        exit(0);
}

運行結果:
windeal@ubuntu:~/Windeal/apue$ ./exe 
buffer length 16 is too small
time and date: 02:43:55 PM, Thu Aug 28, 2014

字符串轉換成struct tm格式
#include <time.h>
char *strptime(const char *restrictbuf,const char *restrictformat,struct tm *restricttmptr);
                Returns: pointer to one character past last character parsed,NULLotherwise

關於轉換符號:



相關文章
相關標籤/搜索