2014年4月14日 星期一

C 語言 日期與時間的運算及格式化 / C language Date and Time calculate and format

C 語言 日期與時間的運算及格式化

作者:許裕永 Darban

日期與時間的運算及格式化是程式語言必學的項目之一,在 C 語言中運算與格式化時間及日期的函式由標頭檔 time.h提供。

因為在這裡的函式呼叫,無論參數列或返回值均大量的使用指標,沒學過指標的同學請先參閱指標相關章節。


*_* 取得現在時間
函式:time_t time (time_t* timer);
取得自 1970 1 1 00:00 到現在的秒數。在程式中直接使用這個值並不適當。一般而言會使用 stdio.h 中的函式,將它格式化之後再輸出。

型別: time_t
time_t 型別是一個不屬於基本型別的整數擴充型別,用來儲存秒數,只用於時間運算。

參數:time_t*
一個 time_t 型別的指標,運算後會產生一個 time_t 型別的值,儲存此值的記憶體空間的記憶體位址將會被儲存在指標參數之中。
另外,這個參數的值可以是 null ,在這種狀況這個參數將不會被使用,但這個函式仍然會運出 time_t 型別的值並將其做為返回值

返回值
包含目前時間的 time_t 型別的值。.

範例一:
time() 的返回值指派給宣告 time_t 變數。
int main(int argc, char *argv[]) {
        time_t now = time(NULL);
        printf("%d",now);
        return 0;
}

範例二:
宣告指標做為 time() 的參數。
int main(int argc, char *argv[]) {
        time_t* now;
        time(now);
        printf("%d",*now);
        return 0;
}

*_* 格式化 time_t 的值
函式:char* ctime (const time_t * timer);

範例:

int main(int argc, char *argv[]) {
        time_t* now;
        time(now);
       
        printf("The date and time is : %s", ctime(now));
        return 0;
}

*_* 區域化 time_t 的值
函式:struct tm * localtime (const time_t * timer);
time_t 物件轉成區域化之後的 tm 型別物件。

型別: struct tm
這個結構包含了九種 int 型別的成員:

Member
Type
Meaning
Range
tm_sec
int
seconds after the minute
0-61
tm_min
int
minutes after the hour
0-59
tm_hour
int
hours since midnight
0-23
tm_mday
int
day of the month
1-31
tm_mon
int
months since January
0-11
tm_year
int
years since 1900

tm_wday
int
days since Sunday
0-6
tm_yday
int
days since January 1
0-365
tm_isdst
int
Daylight Saving Time flag


參數:time_t*
time_t 型別的物件的記憶體位址。

返回值: struct tm*
struct tm 型別的物件的指標。

範例:

int main(int argc, char *argv[]) {
        time_t* now;
        time(now);
       
        struct tm* localNow = localtime(now);
        printf("%d/%d/%d\n",localNow->tm_year + 1900,localNow->tm_mon +1,localNow->tm_mday);
        printf("%d:%d:%d\n",localNow->tm_hour,localNow->tm_min,localNow->tm_sec);
        return 0;
}

*_* 格式化 struct tm 物件
函式A:char* asctime (const struct tm * timeptr);

範例:

int main(int argc, char *argv[]) {
        time_t* now;
        time(now);
       
        struct tm* now_tm =  localtime(now);
        printf("The date and time is : %s", asctime(now_tm));
        return 0;
}

函式B:size_t strftime (char* ptr, size_t maxsize, const char* format,
                 const struct tm* timeptr );

參數:
|) char* ptr
用來儲存格式化後的文字的指標。

|) size_t maxsize
設定文字的最大長度,包含文字終止符號。

|) char* format
使用下列表格代號,指定格式。

specifier
Replaced by
Example
%a
Abbreviated weekday name *
Thu
%A
Full weekday name *
Thursday
%b
Abbreviated month name *
Aug
%B
Full month name *
August
%c
Date and time representation *
Thu Aug 23 14:55:02 2001
%C
Year divided by 100 and truncated to integer (00-99)
20
%d
Day of the month, zero-padded (01-31)
23
%D
Short MM/DD/YY date, equivalent to %m/%d/%y
08/23/01
%e
Day of the month, space-padded ( 1-31)
23
%F
Short YYYY-MM-DD date, equivalent to %Y-%m-%d
2001-08-23
%g
Week-based year, last two digits (00-99)
01
%G
Week-based year
2001
%h
Abbreviated month name * (same as %b)
Aug
%H
Hour in 24h format (00-23)
14
%I
Hour in 12h format (01-12)
02
%j
Day of the year (001-366)
235
%m
Month as a decimal number (01-12)
08
%M
Minute (00-59)
55
%n
New-line character ('\n')

%p
AM or PM designation
PM
%r
12-hour clock time *
02:55:02 pm
%R
24-hour HH:MM time, equivalent to %H:%M
14:55
%S
Second (00-61)
02
%t
Horizontal-tab character ('\t')

%u
ISO 8601 weekday as number with Monday as 1 (1-7)
4
%U
Week number with the first Sunday as the first day of week one (00-53)
33
%V
ISO 8601 week number (00-53)
34
%w
Weekday as a decimal number with Sunday as 0 (0-6)
4
%W
Week number with the first Monday as the first day of week one (00-53)
34
%x
Date representation *
08/23/01
%X
Time representation *
14:55:02
%y
Year, last two digits (00-99)
01
%Y
Year
2001
%%
A % sign
%

參數 struct tm* timeptr
要格式化的 struct tm 物件的記憶體位址。

範例:

int main(int argc, char *argv[]) {
        time_t* now;
        time(now);
       
        struct tm* now_tm =  localtime(now);
       
        char* date = (char*)malloc(10);
        strftime(date,10,"%x",now_tm);
        printf("The date is : %s\n",date);
       
        char* time = (char*)malloc(10);
        strftime(time,10,"%X",now_tm);
        printf("The time is : %s\n",time);
       
        return 0;
}

*_* 建立指定日期時間的 struct tm 物件
範例一:

int main(int argc, char *argv[]) {
/*
                同一個函式中重複呼叫 localtime() 都是在存取同一個 tm 物件。
                也就是說,即使每次呼叫都指派給不同的 tm 指標,其實這些指標都指向同一個物件。
                所以必須先記錄要運算的值,再修改 tm 欄位中的內容。
        */
       
        //以現在時間建立 tm 物件,填滿其所有欄位
        time_t now;
        time(&now);
        struct tm* birthday = localtime(&now);
       
        //記錄現在的年
        int now_year = birthday->tm_year + 1900;

        //設定指定欄位的值
        birthday->tm_year = 1990 - 1900;
        birthday->tm_mon = 6 - 1;
        birthday->tm_mday = 17;
       
        char* date = (char*)malloc(10);
        strftime(date,10,"%x",birthday);
       
        printf("The birthday is : %s\n" ,date);
        printf("The age is : %d",now_year- (birthday->tm_year + 1900))       ;
        return 0;}

*_* 取得指定日期的tm物件的 time_t
函式: time_t mktime (struct tm * timeptr);

範例:
int main(int argc, char *argv[]) {

        time_t seconds;
        time(&seconds);
        struct tm* day = localtime(&seconds);
       
        day->tm_year = 2014 - 1900;
        day->tm_mon = 3 - 1;
        day->tm_mday = 1;
       
        seconds = mktime(day);
        seconds += 86400 * 300;
        localtime(&seconds);
       
        char* date = (char*)malloc(10);
        strftime(date,10,"%x",day);
       
        printf("The end day is : %s\n" ,date); 

        return 0;
}

*_* 取得兩個日期距離的杪數
函數: double difftime (time_t end, time_t beginning);

範例:
int main(int argc, char *argv[]) {
        time_t day = 0;
        struct tm* day_tm = localtime(&day);
       
        day_tm->tm_year = 2012 - 1900;
        day_tm->tm_mon = 3 - 1;
        day_tm->tm_mday = 5;
        time_t startSecond = mktime(day_tm);
       
        day_tm->tm_year = 2014 - 1900;
        day_tm->tm_mon = 5 - 1;
        day_tm->tm_mday = 15;
        time_t endSecond = mktime(day_tm);      
       
        double seconds = difftime(endSecond, startSecond);
        printf("The days between start day and end day are : %.0f days",seconds/86400);
       
        return 0;


}

沒有留言:

張貼留言