Chuck Allison 是鹽湖城聖 Latter Day 教堂總部下耶穌教堂家族曆史研究處的軟體體系設計師。他擁有數學學士和數學碩士學位。他從1975年起開始編程,從1984年起他開始從事c語言的教學和開發。他目前的興趣是物件導向的技術及其教育。他是X3J16,ANSI C ++標準化委員會的一員。
大部分的作業系統有辦法得到當前的日期和時間。通過定義在time.h的庫函數,ANSI C能以許多不同的形式得到這個資訊。函數time返回一個類型為time_t的值(通常為long),該函數在運行期間對當前的日期和時間進行編碼。然後你可以將這個傳回值傳遞給其他能對該值進行解碼和格式化的函數。
Listing 1 中的程式使用函數time,localtime和strftime以不同的形式輸出當前的日期和時間。函數localtime把已經編碼的時間解碼成如下的struct:
struct tm
{
int tm_sec; /* (0 - 61) */
int tm_min; /* (0 - 59) */
int tm_hour; /* (0 - 23) */
int tm_mday; /* (1 - 31) */
int tm_mon; /* (0 - 11) */
int tm_year; /* past 1900 */
int tm_wday; /* (0 - 6) */
int tm_yday; /* (0 - 365) */
int tm_isdst; /* daylight savings flag */
};
每次當你調用localtime的時候,它會重寫一個靜態結構並返回該結構的地址(因此同一時刻在一個程式中只能取得一個這樣的結構,而不能做明顯的拷貝)。函數ctime返回一個指向靜態字串的指標,該字串以標準的格式包含了完整的時間和日期。strftime根據使用者的指定格式格式化字串(例如,%A代表一周中每一天的名稱)。Table 1列出了格式描述符的完整列表。
時間/日期運算
通過改變tm結構裡的值,可對時間/日期進行運算。Listing 2 中的程式展示了如何計算將來某天的日期和以秒為單位所計算出的程式執行時間。注意函數time的文法(參數time_t由地址傳入,並非作為函數的傳回值)。函數mktime改變tm結構的值,以便日期和時間在一個合適的範圍內,之後day-of-week (tm_wday)和day-of-year (tm_yday)域進行相應的更新。mktime將tm結構中日期和時間的值置於合適的範圍之內,相應的更新day of week (tm-wday)和day of year (tm-yday)的值。這種情況發生在當一個日期超出了你的實現能夠支援的範圍的時候。例如,我的MS-DOS的編譯器不能編碼1970年1月份之前的日期。函數asctime返回tm參數所描述時間的標準字串(因此ctime (&tval)與asctime (localtime(&tval)是相等的)。函數difftime返回用秒做單位的兩個time_t的差。
如果需要處理超出系統範圍的日期,或者需要計算兩個日期的間隔又不是用秒來做單位,那你需要設計自己的date編碼。Listing 3 到 Listing 5 中的應用程式通過使用一個簡單的month-day-year結構,展示了確定兩個日期間隔的年數、月份數和天數的技術。日期的相減就像你在小學裡做的減法那樣(例如,首先進行天數的相減,如果需要就向月份數借位,以此類推)。注意跳過的年份都被計算進去了。為了簡略起見,date_interval函數假設日期都是有效,並且第一個日期在第二個日期之前。函數返回一個指向靜態Date結構的指標,該結構包含了我們想要的答案。