转自:https://www.cnblogs.com/renjiashuo/p/6913668.html

在c/c++实际问题的编程中,我们经常会用到日期与时间的格式,在算法运行中,通常将时间转化为int来进行计算,而处理输入输出的时候,日期时间的格式却是五花八门,以各种标点空格相连或者不加标点。

首先,在c中,是有一个标准的日期时间结构体的,在标准库wchar.h内,我们可以看到结构体tm的声明如下:

 #ifndef _TM_DEFINED
struct tm {
int tm_sec; /* seconds after the minute - [0,59] */
int tm_min; /* minutes after the hour - [0,59] */
int tm_hour; /* hours since midnight - [0,23] */
int tm_mday; /* day of the month - [1,31] */
int tm_mon; /* months since January - [0,11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday - [0,6] */
int tm_yday; /* days since January 1 - [0,365] */
int tm_isdst; /* daylight savings time flag */
};
#define _TM_DEFINED
#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的函数代码。

 time_t StringToDatetime(string str)
{
char *cha = (char*)str.data(); // 将string转换成char*。
tm tm_; // 定义tm结构体。
int year, month, day, hour, minute, second;// 定义时间的各个int临时变量。
sscanf(cha, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 将string存储的日期时间,转换为int临时变量。
tm_.tm_year = year - ; // 年,由于tm结构体存储的是从1900年开始的时间,所以tm_year为int临时变量减去1900。
tm_.tm_mon = month - ; // 月,由于tm结构体的月份存储范围为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 = ; // 非夏令时。
time_t t_ = mktime(&tm_); // 将tm结构体转换成time_t格式。
return t_; // 返回值。
}

其中,第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的函数代码。

 string DatetimeToString(time_t time)
{
tm *tm_ = localtime(&time); // 将time_t格式转换为tm结构体
int year, month, day, hour, minute, second;// 定义时间的各个int临时变量。
year = tm_->tm_year + ; // 临时变量,年,由于tm结构体存储的是从1900年开始的时间,所以临时变量int为tm_year加上1900。
month = tm_->tm_mon + ; // 临时变量,月,由于tm结构体的月份存储范围为0-11,所以临时变量int为tm_mon加上1。
day = tm_->tm_mday; // 临时变量,日。
hour = tm_->tm_hour; // 临时变量,时。
minute = tm_->tm_min; // 临时变量,分。
second = tm_->tm_sec; // 临时变量,秒。
char yearStr[], monthStr[], dayStr[], hourStr[], minuteStr[], secondStr[];// 定义时间的各个char*变量。
sprintf(yearStr, "%d", year); // 年。
sprintf(monthStr, "%d", month); // 月。
sprintf(dayStr, "%d", day); // 日。
sprintf(hourStr, "%d", hour); // 时。
sprintf(minuteStr, "%d", minute); // 分。
if (minuteStr[] == '\0') // 如果分为一位,如5,则需要转换字符串为两位,如05。
{
minuteStr[] = '\0';
minuteStr[] = minuteStr[];
minuteStr[] = '';
}
sprintf(secondStr, "%d", second); // 秒。
if (secondStr[] == '\0') // 如果秒为一位,如5,则需要转换字符串为两位,如05。
{
secondStr[] = '\0';
secondStr[] = secondStr[];
secondStr[] = '';
}
char s[]; // 定义总日期时间char*变量。
sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 将年月日时分秒合并。
string str(s); // 定义string变量,并将总日期时间char*变量作为构造函数的参数传入。
return str; // 返回转换日期时间后的string变量。
}

其中,第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。

  #include <iostream>
#include <ctime>
#include <string>
using namespace std;
time_t StringToDatetime(string str)
{
char *cha = (char*)str.data(); // 将string转换成char*。
tm tm_; // 定义tm结构体。
int year, month, day, hour, minute, second;// 定义时间的各个int临时变量。
sscanf(cha, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);// 将string存储的日期时间,转换为int临时变量。
tm_.tm_year = year - ; // 年,由于tm结构体存储的是从1900年开始的时间,所以tm_year为int临时变量减去1900。
tm_.tm_mon = month - ; // 月,由于tm结构体的月份存储范围为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 = ; // 非夏令时。
time_t t_ = mktime(&tm_); // 将tm结构体转换成time_t格式。
return t_; // 返回值。
}
string DatetimeToString(time_t time)
{
tm *tm_ = localtime(&time); // 将time_t格式转换为tm结构体
int year, month, day, hour, minute, second;// 定义时间的各个int临时变量。
year = tm_->tm_year + ; // 临时变量,年,由于tm结构体存储的是从1900年开始的时间,所以临时变量int为tm_year加上1900。
month = tm_->tm_mon + ; // 临时变量,月,由于tm结构体的月份存储范围为0-11,所以临时变量int为tm_mon加上1。
day = tm_->tm_mday; // 临时变量,日。
hour = tm_->tm_hour; // 临时变量,时。
minute = tm_->tm_min; // 临时变量,分。
second = tm_->tm_sec; // 临时变量,秒。
char yearStr[], monthStr[], dayStr[], hourStr[], minuteStr[], secondStr[];// 定义时间的各个char*变量。
sprintf(yearStr, "%d", year); // 年。
sprintf(monthStr, "%d", month); // 月。
sprintf(dayStr, "%d", day); // 日。
sprintf(hourStr, "%d", hour); // 时。
sprintf(minuteStr, "%d", minute); // 分。
if (minuteStr[] == '\0') // 如果分为一位,如5,则需要转换字符串为两位,如05。
{
minuteStr[] = '\0';
minuteStr[] = minuteStr[];
minuteStr[] = '';
}
sprintf(secondStr, "%d", second); // 秒。
if (secondStr[] == '\0') // 如果秒为一位,如5,则需要转换字符串为两位,如05。
{
secondStr[] = '\0';
secondStr[] = secondStr[];
secondStr[] = '';
}
char s[]; // 定义总日期时间char*变量。
sprintf(s, "%s-%s-%s %s:%s:%s", yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);// 将年月日时分秒合并。
string str(s); // 定义string变量,并将总日期时间char*变量作为构造函数的参数传入。
return str; // 返回转换日期时间后的string变量。
}
int main()
{
string timeStr = "2017-05-27 19:50:02";
cout << timeStr << endl;
time_t timet = StringToDatetime(timeStr);
timet += * * ;
string timeStr2 = DatetimeToString(timet);
cout << timeStr2 << endl;
return ;
}

主函数中给定一个字符串"2017-05-27 19:50:02"。

经过增加5*24*3600秒之后,得到的字符串是"2017-6-1 19:50:02"。

c/c++日期时间处理与字符串string转换的更多相关文章

  1. Sql Server中日期时间格式化为字符串输出

    在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...

  2. Java 日期时间与unix时间戳之间转换

    日期时间  <-->  时间戳 java.time 包提供的新的日期和时间API LocalDateTime: 本地日期时间类 ZoneId: 时区类 ZonedDateTime: 带时区 ...

  3. 字符串类型日期时间转换为Date类型解析转换异常java.text.ParseException: Unparseable date: “2019-09-27T18:31:31+08:00”

    错误的写法: SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //这里的格式也可以是别 ...

  4. [转]JDBC中日期时间的处理技巧

    Java中用类java.util.Date对日期/时间做了封装,此类提供了对年.月.日.时.分.秒.毫秒以及时区的控制方法,同时也提供一些工具方法,比如日期/时间的比较,前后判断等. java.uti ...

  5. 一起Polyfill系列:让Date识别ISO 8601日期时间格式

    一.什么是ISO 8601日期时间格式 ISO 8601是国际标准化组织制定的日期时间表示规范,全称是<数据存储和交换形式·信息交换·日期和时间的表示方法>. 示例: 1. 2014-12 ...

  6. 自己封装的一个js方法用于获取显示的星期和日期时间

    自己封装的一个js方法用于获取显示的星期和日期时间 /** * 获取用于显示的星期和日期时间 * @param date * @returns {string} */ function getWeek ...

  7. Java8 新特性(三) - 日期时间对象以及一些其他特性

    日期时间对象 关于日期时间的操作可以分为两种: 转换:与字符串的互相转换,与时间戳的互相转换 计算:计算两个时间点之间的间隔.时间点与时间段的计算(计算下周N.下个月D日.去年M月D日等等) Java ...

  8. Apache Commons Lang之日期时间工具类

    码农不识Apache,码尽一生也枉然. FastDateFormat FastDateFormat是一个快速且线程安全的时间操作类,它完全可以替代SimpleDateFromat.因为是线程安全的,所 ...

  9. 详解 JDK8 新增的日期时间类

    JDK8 新增的日期时间类 在本人之前的博文<处理时间的类 -- System类.Date类 .SimpleDateFormat类 与 Calendar类>中,讲到过表示时间的类,有三类: ...

随机推荐

  1. Spark2 生存分析Survival regression

    在spark.ml中,实现了加速失效时间(AFT)模型,这是一个用于检查数据的参数生存回归模型. 它描述了生存时间对数的模型,因此它通常被称为生存分析的对数线性模型. 不同于为相同目的设计的比例风险模 ...

  2. flask BytesIO() 多个文件打包下载 zipfile

    使用zipfile模块可以将多个文件打包成zip文件进行下载,但是常规的操作方式会在服务器磁盘上生成一个zip文件占用磁盘空间. 后引入BytesIO将文件写入到内存中然后下载: def dl_pla ...

  3. 9.7 Django 书单列表页面

    昨天的迭代版本,增加了编辑出版社,编辑列表,增添了返回页面! 具体的看 github : https://github.com/TrueNewBee/pythonDemo 看一下效果图: 整体来说还是 ...

  4. ICSharpCode.SharpZipLib.dll 压缩多文件

    网站:http://icsharpcode.github.io/SharpZipLib/ 引用:ICSharpCode.SharpZipLib.dll private string CompassZi ...

  5. poj3728The merchant 【倍增】【LCA】

    There are N cities in a country, and there is one and only one simple path between each pair of citi ...

  6. POJ - 1101 The Game dfs

    题意:给你一个地图,上面有一些‘X',给你起点终点,让你输出从起点到终点的路径中转向(改变方向)次数最少的路径,注意,不能穿过别的’X'并且可以超过边界 题解:关于超过边界,只要在外围多加一圈‘ ’. ...

  7. Cloudrea manager5安装CDH5文档

    一.主机规划.存储规划 服务器配置信息:CentOS6.5 最小化安装+development tools组包,其余组件yum安装即可. 二.系统设置如下: 1.服务器信息如下(/etc/hosts文 ...

  8. Golang 序列化方式及对比

    Golang 序列化方式及对比 - fengfengdiandia的专栏 - CSDN博客 https://blog.csdn.net/fengfengdiandia/article/details/ ...

  9. Iwconfig/aircrack-ng

    BT5 aircrack-ng破解无线密码(wpa/wep) - 星明月稀 - 博客频道 - CSDN.NET             BT5 aircrack-ng破解无线密码(wpa/wep) - ...

  10. Networking---poj1287最小生成树

    http://poj.org/problem?id=1287 最小生成树模板题类似的还有:poj1258  hdu1233代码几乎一样: 最小生成树详解 #include<stdio.h> ...