转自: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. thinkCMF----公共模板的引入

    这个主要用于前台模板的 头部和底部分离: 具体引入方法: <include file="public@source"/> <include file=" ...

  2. Docker 安装Centos,Tomcat,Jdk等相关的自定义(Dockerfile)镜像

    一.安装Centos镜像 这里Centos 安装 国内daocloud网站提供的官方镜像 docker pull daocloud.io/library/centos:latest 利用docker  ...

  3. URL长度过长的问题

    最近项目中很多跨域的问题,有时候跨域要传递很多参数,甚至有时候要传递整个对象,处理的方法是把对象转换成JSON形式的字符串再传递.此时该JSON字符串就比较长,作为参数附加到URL后面,URL就会变得 ...

  4. HUST 1599 - Multiple(动态规划)

    1599 - Multiple 时间限制:2秒 内存限制:64兆 461 次提交 111 次通过 题目描述 Rocket323 loves math very much. One day, Rocke ...

  5. 20144306《网络对抗》Web基础

    1  实验内容 Web前端HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. Web前端javascipt:理解JavaScript ...

  6. java数据库三大范式

    引用知乎网友@ 王红波的回答 一范式就是属性不可分割.属性是什么?就是表中的字段.不可分割的意思就按字面理解就是最小单位,不能再分成更小单位了.这个字段只能是一个值,不能被拆分成多个字段,否则的话,它 ...

  7. Mayor's posters---poj2528线段树、离散化

    题目链接:http://poj.org/problem?id=2528 题意:有n张海报要贴,每张需要用的区间为L到R,后面的可以贴在之前的上面,就是吧之前的挡住,求最后我们能看到几张海报: 我们可以 ...

  8. CCO2017 Vera and Trail Building 构造+图论

    正解:构造+图论 解题报告: 找了半天才找到的传送门! 先简要表达下题意 一个图上,如果存在(a,b)满足a<b且存在从a到b再回到a的路径,每条道路被经过至多一次,我们称(a,b)为完美点对试 ...

  9. PyQt5标准对话框

    很全的Qt的标准对话框,包含QInputDialog.QColorDialog.QFontDialog.QMessageBox.QOpenFileDialog... 全部是由官网的C++版本,转换成P ...

  10. 通过phantomjs 进行页面截图

    本文章参考了使用phantomjs操作DOM并对页面进行截图需要注意的几个问题 及phantomjs使用说明 这两篇文章,初次接触phantomjs的童鞋可以去看下这两篇原文 在学习中可以看下 pha ...