cc++⽇期时间处理与字符串string转换
在c/c++实际问题的编程中,我们经常会⽤到⽇期与时间的格式,在算法运⾏中,通常将时间转化为int来进⾏计算,⽽处理输⼊输出的时候,⽇期时间的格式却是五花⼋门,以各种标点空格相连或者不加标点。
⾸先,在c中,是有⼀个标准的⽇期时间结构体的,在标准库wchar.h内,我们可以看到结构体tm的声明如下:
1 #ifndef _TM_DEFINED
2struct tm {
3int tm_sec; /* seconds after the minute - [0,59] */
4int tm_min; /* minutes after the hour - [0,59] */
5int tm_hour; /* hours since midnight - [0,23] */
6int tm_mday; /* day of the month - [1,31] */
7int tm_mon; /* months since January - [0,11] */
8int tm_year; /* years since 1900 */
9int tm_wday; /* days since Sunday - [0,6] */
10int tm_yday; /* days since January 1 - [0,365] */
11int 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环境下,就是"__int64"类型的变量,它由typedef关键字在库⽂件crtdefs.h⾥给定,所以,把time_t放⼼的拿去⽤就好了。
⾔归正传,这⾥,我们假定输⼊的字符串格式为"2017-05-27 19:50:02",这个设定并不影响其他格式的字符串时间与可参与计算的变量的转换,如果要参与转换的⽇期字符串不是这个格式,读者可⾃⾏更改下⾯给出代码的对应部分。
下⾯给出⽇期时间string转换为time_t的函数代码。
日期转字符串函数1 time_t StringToDatetime(string str)
2 {
3char *cha = (char*)str.data(); // 将string转换成char*。
4 tm tm_; // 定义tm结构体。
5int 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格式。
15return 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的函数代码。
1string DatetimeToString(time_t time)
2 {
3 tm *tm_ = localtime(&time); // 将time_t格式转换为tm结构体
4int 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; // 临时变量,秒。
11char 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); // 分。
17if (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); // 秒。
24if (secondStr[1] == '\0') // 如果秒为⼀位,如5,则需要转换字符串为两位,如05。
25 {
26 secondStr[2] = '\0';
27 secondStr[1] = secondStr[0];
28 secondStr[0] = '0';
29 }
30char s[20]; // 定义总⽇期时间char*变量。
31 sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 将年⽉⽇时分秒合并。
32string str(s); // 定义string变量,并将总⽇期时间char*变量作为构造函数的参数传⼊。
33return 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>
4using namespace std;
5 time_t StringToDatetime(string str)
6 {
7char *cha = (char*)str.data(); // 将string转换成char*。
8 tm tm_; // 定义tm结构体。
9int 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格式。
19return t_; // 返回值。
20 }
21string DatetimeToString(time_t time)
22 {
23 tm *tm_ = localtime(&time); // 将time_t格式转换为tm结构体
24int 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; // 临时变量,秒。
31char 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); // 分。
37if (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); // 秒。
44if (secondStr[1] == '\0') // 如果秒为⼀位,如5,则需要转换字符串为两位,如05。
45 {
46 secondStr[2] = '\0';
47 secondStr[1] = secondStr[0];
48 secondStr[0] = '0';
49 }
50char s[20]; // 定义总⽇期时间char*变量。
51 sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 将年⽉⽇时分秒合并。52string str(s); // 定义string变量,并将总⽇期时间char*变量作为构造函数的参数传⼊。
53return str; // 返回转换⽇期时间后的string变量。
54 }
55int main()
56 {
57string timeStr = "2017-05-27 19:50:02";
58 cout << timeStr << endl;
59 time_t timet = StringToDatetime(timeStr);
60 timet += 5 * 24 * 3600;
61string timeStr2 = DatetimeToString(timet);
62 cout << timeStr2 << endl;
63return0;
64 }
主函数中给定⼀个字符串"2017-05-27 19:50:02"。
经过增加5*24*3600秒之后,得到的字符串是"2017-6-1 19:50:02"。
端午节过了就到⼉童节啦,完结撒花!*★,°*:。☆\(~▽~)/$:*。°★*。。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论