當(dāng)前位置:首頁 > IT技術(shù) > 編程語言 > 正文

C++ time_t與string的互相轉(zhuǎn)換
2021-11-16 11:33:39

轉(zhuǎn)載:https://www.cnblogs.com/renjiashuo/p/6913668.html

在c/c++實(shí)際問題的編程中,我們經(jīng)常會用到日期與時間的格式,在算法運(yùn)行中,通常將時間轉(zhuǎn)化為int來進(jìn)行計(jì)算,而處理輸入輸出的時候,日期時間的格式卻是五花八門,以各種標(biāo)點(diǎn)空格相連或者不加標(biāo)點(diǎn)。

首先,在c中,是有一個標(biāo)準(zhǔn)的日期時間結(jié)構(gòu)體的,在標(biāo)準(zhǔn)庫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 */

由于各項(xiàng)英文注釋很好理解,這里只做簡要補(bǔ)充。

1)注意月份是0-11,而不是1-12,所以在tm結(jié)構(gòu)體與string轉(zhuǎn)換的時候,要相應(yīng)的做減1加1處理。

2)tm_isdst為夏令時設(shè)置,0為非夏令時,1為夏令時。由于21世紀(jì)的中國并沒有實(shí)行夏令時制度,所以編寫國內(nèi)程序我們可以忽略這個變量。

利用這個結(jié)構(gòu)體,我們就可以完成日期時間與string字符串的轉(zhuǎn)換了,由于計(jì)算的方便,我們一般選擇將日期時間的string轉(zhuǎn)換成time_t類型。

如果你非要int的話,我可以負(fù)責(zé)任的告訴你,time_t在visual studio環(huán)境下,就是"__int64"類型的變量,它由typedef關(guān)鍵字在庫文件crtdefs.h里給定,所以,把time_t放心的拿去用就好了。

言歸正傳,這里,我們假定輸入的字符串格式為"2017-05-27 19:50:02",這個設(shè)定并不影響其他格式的字符串時間與可參與計(jì)算的變量的轉(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è)計(jì)到多種不同的日期時間格式,可以將這個參數(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通常很大,不利于算法計(jì)算的效率,所以我們可以將所有的時間轉(zhuǎn)換完畢后,將所有的time_t全部減去一個數(shù),這個數(shù)可以是這個time_t中最小的那個數(shù),也可以是其他方便算法計(jì)算的數(shù)。在算法執(zhí)行完畢之后,我們再將結(jié)果的時間全部加上這個數(shù),以便將時間轉(zhuǎn)換回來。

現(xiàn)在假定我們已經(jīng)將算法運(yùn)行完畢,那么我們需要將結(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] == '