C/C++时间处理的易错点
在C/C+++中,我用到的关于时间的表达类型主要有3种,分别是time_t类型、tm类型、ptime类型,其中ptime类型来自于boost库,对时间的加减等操作十分友好,使用起来最为方便。
tm类型是一个直接存储年月的结构体:
struct tm
{
int tm_sec; // seconds after the minute - [0, 60] including leap second
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
};
关于这个表示时间的结构体有3个地方需要特别的注意:
1、年份计算是从1900年起至今多少年,而不是直接存储年份如2020年;
2、它的tm_mday大多按照人类思维设计的,除了tm_mon(0-11),也就是6月份的时候你打印出来的这个值是5;
3、tm_wday表示一周中的第几天,是从星期日算起(0-6)
在代码中使用tm格式的时间会遇到的问题就是对tm格式时间的tm_mday进行加法操作的时候会出现大于31天的结果,时分秒月应该也会有此情况,工作太多来不及写demo测试了。
而使用mktime(struct tm* timeptr)将上述超出每月31天的时间转换成time_t格式会得到正确的时间,包括tm格式的时间也会被纠正,但是直接使用boost库的时间转换函数boost::posix_time::ptime_from_tm(const tm &timetm)转换超出范围的tm格式时间则会报错,最直接的解决办法是先将tm转换成time_t格式再使用boost::posix_time::from_time_t(time_t t)进行转换。
既然如此麻烦,我们何不直接使用boost时间库呢,直接对时间操作得到合理的时间。
比如获取当前时间:
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
当前时间增加一天(会自动根据现实时间进行转换,比如5.31日增加一天是6.1日)
boost::posix_time::ptime time = now + boost::gregorian::days(1);
ptime转换成tm:
tm tmTime = boost::posix_time::to_tm(time);
ptime转换成time_t:
time_t timeTemp = boost::posix_time::to_time_t(time);