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