轉載:https://www.cnblogs.com/renjiashuo/p/6913668.html
在c/c++實際問題的編程中,我們經(jīng)常會用到日期與時間的格式,在算法運行中,通常將時間轉化為int來進行計算,而處理輸入輸出的時候,日期時間的格式卻是五花八門,以各種標點空格相連或者不加標點。
首先,在c中,是有一個標準的日期時間結構體的,在標準庫wchar.h內,我們可以看到結構體tm的聲明如下:
1 #ifndef _TM_DEFINED 2 struct tm { 3 int tm_sec; /* seconds after the minute - [0,59] */ 4 int tm_min; /* minutes after the hour - [0,59] */ 5 int tm_hour; /* hours since midnight - [0,23] */ 6 int tm_mday; /* day of the month - [1,31] */ 7 int tm_mon; /* months since January - [0,11] */ 8 int tm_year; /* years since 1900 */ 9 int tm_wday; /* days since Sunday - [0,6] */ 10 int tm_yday; /* days since January 1 - [0,365] */ 11 int tm_isdst; /* daylight savings time flag */ 12 }; 13 #define _TM_DEFINED 14 #endif /* _TM_DEFINED */
由于各項英文注釋很好理解,這里只做簡要補充。
1)注意月份是0-11,而不是1-12,所以在tm結構體與string轉換的時候,要相應的做減1加1處理。
2)tm_isdst為夏令時設置,0為非夏令時,1為夏令時。由于21世紀的中國并沒有實行夏令時制度,所以編寫國內程序我們可以忽略這個變量。
利用這個結構體,我們就可以完成日期時間與string字符串的轉換了,由于計算的方便,我們一般選擇將日期時間的string轉換成time_t類型。
如果你非要int的話,我可以負責任的告訴你,time_t在visual studio環(huán)境下,就是"__int64"類型的變量,它由typedef關鍵字在庫文件crtdefs.h里給定,所以,把time_t放心的拿去用就好了。
言歸正傳,這里,我們假定輸入的字符串格式為"2017-05-27 19:50:02",這個設定并不影響其他格式的字符串時間與可參與計算的變量的轉換,如果要參與轉換的日期字符串不是這個格式,讀者可自行更改下面給出代碼的對應部分。
下面給出日期時間string轉換為time_t的函數(shù)代碼。
time_t StringToDatetime(string str) { char *cha = (char*)str.data(); // 將string轉換成char*。 tm tm_; // 定義tm結構體。 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 sscanf(cha, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 將string存儲的日期時間,轉換為int臨時變量。 tm_.tm_year = year - 1900; // 年,由于tm結構體存儲的是從1900年開始的時間,所以tm_year為int臨時變量減去1900。 tm_.tm_mon = month - 1; // 月,由于tm結構體的月份存儲范圍為0-11,所以tm_mon為int臨時變量減去1。 tm_.tm_mday = day; // 日。 tm_.tm_hour = hour; // 時。 tm_.tm_min = minute; // 分。 tm_.tm_sec = second; // 秒。 tm_.tm_isdst = 0; // 非夏令時。 time_t t_ = mktime(&tm_); // 將tm結構體轉換成time_t格式。 return t_; // 返回值。 }
其中,第6行為給定的日期string設置語句,由于這里假定是輸入的string是"2017-05-27 19:50:02",所以將參數(shù)設置為"%d-%d-%d %d:%d:%d",如果輸入的是其他格式的日期時間形式,將這個參數(shù)改為對應的格式即可。另外,如果在一個程序中,設計到多種不同的日期時間格式,可以將這個參數(shù)作為這個函數(shù)的參數(shù)之一來給定。
第14行的mktime函數(shù)位于c頭文件time.h中,用來將輸入?yún)?shù)所指的tm結構數(shù)據(jù)轉換成從公元1970年1月1日0時0分0秒算起至今的本地時間所經(jīng)過的秒數(shù)。
由于返回的time_t通常很大,不利于算法計算的效率,所以我們可以將所有的時間轉換完畢后,將所有的time_t全部減去一個數(shù),這個數(shù)可以是這個time_t中最小的那個數(shù),也可以是其他方便算法計算的數(shù)。在算法執(zhí)行完畢之后,我們再將結果的時間全部加上這個數(shù),以便將時間轉換回來。
現(xiàn)在假定我們已經(jīng)將算法運行完畢,那么我們需要將結果的time_t轉換為之前給定的string格式以便于結果的展示。
下面給出日期時間time_t轉換為string的函數(shù)代碼。
string DatetimeToString(time_t time) { tm *tm_ = localtime(&time); // 將time_t格式轉換為tm結構體 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 year = tm_->tm_year + 1900; // 臨時變量,年,由于tm結構體存儲的是從1900年開始的時間,所以臨時變量int為tm_year加上1900。 month = tm_->tm_mon + 1; // 臨時變量,月,由于tm結構體的月份存儲范圍為0-11,所以臨時變量int為tm_mon加上1。 day = tm_->tm_mday; // 臨時變量,日。 hour = tm_->tm_hour; // 臨時變量,時。 minute = tm_->tm_min; // 臨時變量,分。 second = tm_->tm_sec; // 臨時變量,秒。 char yearStr[5], monthStr[3], dayStr[3], hourStr[3], minuteStr[3], secondStr[3];// 定義時間的各個char*變量。 sprintf(yearStr, "%d", year); // 年。 sprintf(monthStr, "%d", month); // 月。 sprintf(dayStr, "%d", day); // 日。 sprintf(hourStr, "%d", hour); // 時。 sprintf(minuteStr, "%d", minute); // 分。 if (minuteStr[1] == '