轉自:https://www.cnblogs.com/renjiashuo/p/6913668.htmlhtml
在c/c++實際問題的編程中,咱們常常會用到日期與時間的格式,在算法運行中,一般將時間轉化爲int來進行計算,而處理輸入輸出的時候,日期時間的格式倒是五花八門,以各類標點空格相連或者不加標點。ios
首先,在c中,是有一個標準的日期時間結構體的,在標準庫wchar.h內,咱們能夠看到結構體tm的聲明以下:c++
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世紀的中國並無實行夏令時制度,因此編寫國內程序咱們能夠忽略這個變量。windows
利用這個結構體,咱們就能夠完成日期時間與string字符串的轉換了,因爲計算的方便,咱們通常選擇將日期時間的string轉換成time_t類型。函數
若是你非要int的話,我能夠負責任的告訴你,time_t在visual studio環境下,就是"__int64"類型的變量,它由typedef關鍵字在庫文件crtdefs.h裏給定,因此,把time_t放心的拿去用就行了。測試
言歸正傳,這裏,咱們假定輸入的字符串格式爲"2017-05-27 19:50:02",這個設定並不影響其餘格式的字符串時間與可參與計算的變量的轉換,若是要參與轉換的日期字符串不是這個格式,讀者可自行更改下面給出代碼的對應部分。spa
下面給出日期時間string轉換爲time_t的函數代碼。設計
1 time_t StringToDatetime(string str) 2 { 3 char *cha = (char*)str.data(); // 將string轉換成char*。 4 tm tm_; // 定義tm結構體。 5 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 6 sscanf(cha, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 將string存儲的日期時間,轉換爲int臨時變量。 7 tm_.tm_year = year - 1900; // 年,因爲tm結構體存儲的是從1900年開始的時間,因此tm_year爲int臨時變量減去1900。 8 tm_.tm_mon = month - 1; // 月,因爲tm結構體的月份存儲範圍爲0-11,因此tm_mon爲int臨時變量減去1。 9 tm_.tm_mday = day; // 日。 10 tm_.tm_hour = hour; // 時。 11 tm_.tm_min = minute; // 分。 12 tm_.tm_sec = second; // 秒。 13 tm_.tm_isdst = 0; // 非夏令時。 14 time_t t_ = mktime(&tm_); // 將tm結構體轉換成time_t格式。 15 return t_; // 返回值。 16 }
其中,第6行爲給定的日期string設置語句,因爲這裏假定是輸入的string是"2017-05-27 19:50:02",因此將參數設置爲"%d-%d-%d %d:%d:%d",若是輸入的是其餘格式的日期時間形式,將這個參數改成對應的格式便可。另外,若是在一個程序中,設計到多種不一樣的日期時間格式,能夠將這個參數做爲這個函數的參數之一來給定。
第14行的mktime函數位於c頭文件time.h中,用來將輸入參數所指的tm結構數據轉換成從公元1970年1月1日0時0分0秒算起至今的本地時間所通過的秒數。
因爲返回的time_t一般很大,不利於算法計算的效率,因此咱們能夠將全部的時間轉換完畢後,將全部的time_t所有減去一個數,這個數能夠是這個time_t中最小的那個數,也能夠是其餘方便算法計算的數。在算法執行完畢以後,咱們再將結果的時間所有加上這個數,以便將時間轉換回來。
如今假定咱們已經將算法運行完畢,那麼咱們須要將結果的time_t轉換爲以前給定的string格式以便於結果的展現。
下面給出日期時間time_t轉換爲string的函數代碼。
1 string DatetimeToString(time_t time) 2 { 3 tm *tm_ = localtime(&time); // 將time_t格式轉換爲tm結構體 4 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 5 year = tm_->tm_year + 1900; // 臨時變量,年,因爲tm結構體存儲的是從1900年開始的時間,因此臨時變量int爲tm_year加上1900。 6 month = tm_->tm_mon + 1; // 臨時變量,月,因爲tm結構體的月份存儲範圍爲0-11,因此臨時變量int爲tm_mon加上1。 7 day = tm_->tm_mday; // 臨時變量,日。 8 hour = tm_->tm_hour; // 臨時變量,時。 9 minute = tm_->tm_min; // 臨時變量,分。 10 second = tm_->tm_sec; // 臨時變量,秒。 11 char yearStr[5], monthStr[3], dayStr[3], hourStr[3], minuteStr[3], secondStr[3];// 定義時間的各個char*變量。 12 sprintf(yearStr, "%d", year); // 年。 13 sprintf(monthStr, "%d", month); // 月。 14 sprintf(dayStr, "%d", day); // 日。 15 sprintf(hourStr, "%d", hour); // 時。 16 sprintf(minuteStr, "%d", minute); // 分。 17 if (minuteStr[1] == '\0') // 若是分爲一位,如5,則須要轉換字符串爲兩位,如05。 18 { 19 minuteStr[2] = '\0'; 20 minuteStr[1] = minuteStr[0]; 21 minuteStr[0] = '0'; 22 } 23 sprintf(secondStr, "%d", second); // 秒。 24 if (secondStr[1] == '\0') // 若是秒爲一位,如5,則須要轉換字符串爲兩位,如05。 25 { 26 secondStr[2] = '\0'; 27 secondStr[1] = secondStr[0]; 28 secondStr[0] = '0'; 29 } 30 char s[20]; // 定義總日期時間char*變量。 31 sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 將年月日時分秒合併。 32 string str(s); // 定義string變量,並將總日期時間char*變量做爲構造函數的參數傳入。 33 return str; // 返回轉換日期時間後的string變量。 34 }
其中,第3行的localtime函數位於c頭文件time.h中,用來將從公元1970年1月1日0時0分0秒算起至今的本地時間所通過的秒數轉換成標準tm結構體。
第31行是輸出日期時間字符串string格式的給定,若是須要其餘格式,能夠修改"%s-%s-%s %s:%s:%s"爲指定格式,若是在同一個程序裏須要多種格式的輸出,能夠將這個參數做爲本函數的參數來輸入。
下面給出完整調試用程序及所需頭文件,代碼測試經過環境windows10 + vs2013;Ubuntu 14.04 + gcc version 4.8.2。
1 #include <iostream> 2 #include <ctime> 3 #include <string> 4 using namespace std; 5 time_t StringToDatetime(string str) 6 { 7 char *cha = (char*)str.data(); // 將string轉換成char*。 8 tm tm_; // 定義tm結構體。 9 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 10 sscanf(cha, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 將string存儲的日期時間,轉換爲int臨時變量。 11 tm_.tm_year = year - 1900; // 年,因爲tm結構體存儲的是從1900年開始的時間,因此tm_year爲int臨時變量減去1900。 12 tm_.tm_mon = month - 1; // 月,因爲tm結構體的月份存儲範圍爲0-11,因此tm_mon爲int臨時變量減去1。 13 tm_.tm_mday = day; // 日。 14 tm_.tm_hour = hour; // 時。 15 tm_.tm_min = minute; // 分。 16 tm_.tm_sec = second; // 秒。 17 tm_.tm_isdst = 0; // 非夏令時。 18 time_t t_ = mktime(&tm_); // 將tm結構體轉換成time_t格式。 19 return t_; // 返回值。 20 } 21 string DatetimeToString(time_t time) 22 { 23 tm *tm_ = localtime(&time); // 將time_t格式轉換爲tm結構體 24 int year, month, day, hour, minute, second;// 定義時間的各個int臨時變量。 25 year = tm_->tm_year + 1900; // 臨時變量,年,因爲tm結構體存儲的是從1900年開始的時間,因此臨時變量int爲tm_year加上1900。 26 month = tm_->tm_mon + 1; // 臨時變量,月,因爲tm結構體的月份存儲範圍爲0-11,因此臨時變量int爲tm_mon加上1。 27 day = tm_->tm_mday; // 臨時變量,日。 28 hour = tm_->tm_hour; // 臨時變量,時。 29 minute = tm_->tm_min; // 臨時變量,分。 30 second = tm_->tm_sec; // 臨時變量,秒。 31 char yearStr[5], monthStr[3], dayStr[3], hourStr[3], minuteStr[3], secondStr[3];// 定義時間的各個char*變量。 32 sprintf(yearStr, "%d", year); // 年。 33 sprintf(monthStr, "%d", month); // 月。 34 sprintf(dayStr, "%d", day); // 日。 35 sprintf(hourStr, "%d", hour); // 時。 36 sprintf(minuteStr, "%d", minute); // 分。 37 if (minuteStr[1] == '\0') // 若是分爲一位,如5,則須要轉換字符串爲兩位,如05。 38 { 39 minuteStr[2] = '\0'; 40 minuteStr[1] = minuteStr[0]; 41 minuteStr[0] = '0'; 42 } 43 sprintf(secondStr, "%d", second); // 秒。 44 if (secondStr[1] == '\0') // 若是秒爲一位,如5,則須要轉換字符串爲兩位,如05。 45 { 46 secondStr[2] = '\0'; 47 secondStr[1] = secondStr[0]; 48 secondStr[0] = '0'; 49 } 50 char s[20]; // 定義總日期時間char*變量。 51 sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 將年月日時分秒合併。 52 string str(s); // 定義string變量,並將總日期時間char*變量做爲構造函數的參數傳入。 53 return str; // 返回轉換日期時間後的string變量。 54 } 55 int main() 56 { 57 string timeStr = "2017-05-27 19:50:02"; 58 cout << timeStr << endl; 59 time_t timet = StringToDatetime(timeStr); 60 timet += 5 * 24 * 3600; 61 string timeStr2 = DatetimeToString(timet); 62 cout << timeStr2 << endl; 63 return 0; 64 }
主函數中給定一個字符串"2017-05-27 19:50:02"。
通過增長5*24*3600秒以後,獲得的字符串是"2017-6-1 19:50:02"。