转自: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. Linux下实现秒级定时任务的两种方案

    Linux下实现秒级定时任务的两种方案(Crontab 每秒运行): 第一种方案,当然是写一个后台运行的脚本一直循环,然后每次循环sleep一段时间. while true ;do command s ...

  2. UVA 11768 - Lattice Point or Not

    首先本题需要用到扩展欧几里得算法…… 关于exgcd算法的一点简略证明: 那么,对于函数exgcd(a,b)=(d,x,y),其中d满足d=gcd(a,b); (x,y)满足ax+by=d; 则exg ...

  3. iOS服务器证书不受信任的解决版本

    参考文章链接: https://www.cnblogs.com/v-jing/p/6008964.html http://www.cocoachina.com/ios/20151021/13722.h ...

  4. 自定义vueawesomeswiper分页器样式

    swiperOption: {//swiper的配置项 notNextTick: true,//想获得swiper实例对象,这个必须为true direction: 'vertical', // gr ...

  5. 一致性 hash 算法(转)

    add by zhj:介绍了什么是一致性hash,以及实现一致性hash的一种算法. 原文:http://my.oschina.net/u/195065/blog/193614 目录[-] 一致性 h ...

  6. hbuilder和sublime的autoprefixer安装或者里sass的$mixin处理浏览器前缀

    Autoprefixer是一个后处理程序,不象Sass以及Stylus之类的预处理器.它适用于普通的CSS,可以实现css3代码自动补全.也可以轻松跟Sass,LESS及Stylus集成,在CSS编译 ...

  7. python 面向对象 析构方法

    实例化但从来没有调用他,就浪费了,就应该自动删除它 这个实例一直存在内存里 python有个垃圾自动回收机制 , 每段时间会自动刷新整个内存,把内存垃圾东西删除   析构函数: 在实例释放.销毁的时候 ...

  8. SqlServer--bat批处理执行sql语句1-osql

    首先需要知道,此处使用的批处理命令是osql ,如果安装了SqlServer,目录类似: D:\Program Files\Microsoft SQL Server\100\Tools\Binn 脚本 ...

  9. 前端js如何生成一个对象,并转化为json字符串

    https://www.cnblogs.com/May-day/p/6841958.html 一,直接上代码 <script src="../../Content/jquery-2.0 ...

  10. python对象反射和函数反射

    python的对象反射功能,经常在编程时使用.相比较其它的编程语言使用非常方便.反射就是用字符串来操作对象或者类,模块中的成员. 一.对象的反射 反射功能的实现,由这4个内置函数来实现(hasattr ...