转自: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"。