C 向tm结构添加一些间隔
我有一个struct tm。C 向tm结构添加一些间隔,c,time-t,ctime,C,Time T,Ctime,我有一个struct tm。 我需要增加一些固定的时间间隔(以xx年,xx月,xx天为单位) 到tm结构。 有没有标准的函数来实现这一点 我使用的编译器是Windows XP上的MSVC 2005。标准加法运算符可以工作 struct tm x; /* add 2 years and 3 days to x */ x.tm_year += 2; x.tm_mday += 3; 编辑:您可以轻松创建函数 struct tm addinterval(struct tm x, int y, int
我需要增加一些固定的时间间隔(以xx年,xx月,xx天为单位) 到tm结构。
有没有标准的函数来实现这一点
我使用的编译器是Windows XP上的MSVC 2005。标准加法运算符可以工作
struct tm x;
/* add 2 years and 3 days to x */
x.tm_year += 2;
x.tm_mday += 3;
编辑:您可以轻松创建函数
struct tm addinterval(struct tm x, int y, int m, int d) {
x.tm_year += y;
x.tm_mon += m;
x.tm_mday += d;
mktime(&x); /* normalize result */
return x;
}
编辑:添加了
mktime
以规范化结果有两个转换时间格式的函数:
mktime()
它将struct tm
(表示本地时间)转换为time\t
localtime()
它在struct tm
中将time
转换为本地时间另请注意
tm_isdst
会员,请关注它。当您跳过夏时制切换日期时,其值可能会导致时间前后移动。我建议先将当前日期转换为天数。那么,添加一个间隔就很简单了。然后,将数字转换回日期
您可以找到将日期转换为若干天并返回的算法,例如
其他答案会导致非常不稳定的结果,具体取决于系统初始化struct tm的方式以及是否正确初始化了中午时间值。
如果您感兴趣的只是日期的更改,而时间保持不变,则在传递到mktime
之前,将tm_isdst
、tm_hour
、tm_sec
全部设置为0。更好的方法是,在之前获取它们的值,并在之后重置它们以保持一致性(如果它们以前不一致,它们将始终保持一致)。重用来自其他答案的代码:
tm addinterval(tm t, int y, int m, int d)
{
auto hour = t.tm_hour;
auto min = t.tm_min;
auto sec = t.tm_sec;
// First we discover the DST Flag. By setting hour to 12
// we can assure the mktime does not shift the date
// because it will shift the hour!
t.tm_isdst = 0;
t.tm_hour = 12;
t.tm_min = 0;
t.tm_sec = 0;
mktime(&t);
// Now we can add the interval
t.tm_year += y;
t.tm_mon += m;
t.tm_mday += d;
mktime(&t);
// Now reset the mid-day time values
t.tm_hour = hour;
t.tm_min = min;
t.tm_sec = sec;
// Return struct tm while keeping mid-day time the same
// while the only values that changed are the date and perhaps isdst.
return t;
}
我希望它更简单,但这正是它必须做到的。+1但要注意溢出,例如,将3个月添加到10个月不会得到13个月,而是得到1年1个月。。。护理是强制性的。“2012-02-29+1年是2013-03-01”非常感谢,简单的添加注意闰耳和月长的差异?例如,如果我将31天的月与28天的月相加,那么这个增加的月在1,天字段在3?@StNickolay:如果你在应用相加后调用
mktime(&x)
,它将使结构正常化(例如10月40日变为11月9日)。我找到了正确的解决方案,谢谢大家。主题结束了。我以前写过,那个修正不起作用。mktime(&x)return-1我认为(希望)DST不会更改结果,因为我们处理的是天,而不是小时。对不起,我在写我的文章时没有看到您的评论。但是mktime
适用于我的GCC。如果编译器不支持c99标准,您的代码可能会失败。@pmg:如果mk time看到时间13:17 Dec,7
withtm_isdst
设置为1,它将尝试设置更正此标志,这将导致时间(可能还有日期)发生更改。如果在mktime()
之前将tm_isdst
设置为-1,则不会发生更改。我对此进行了测试。mktime()
在标准C中始终具有规范化行为,它不需要C99。请告诉我们您使用的编译器和平台(以及它支持的标准,如果您知道的话)。这是为了澄清为什么mk_time
不适合您。即使你已经找到了一个解决方案,它也会帮助其他人。Windows XP,MSVC 2005,我尝试从pmg复制粘贴的代码,无论是否使用MKTIME,它都无法工作请将你的完整测试代码粘贴到这里!
tm addinterval(tm t, int y, int m, int d)
{
auto hour = t.tm_hour;
auto min = t.tm_min;
auto sec = t.tm_sec;
// First we discover the DST Flag. By setting hour to 12
// we can assure the mktime does not shift the date
// because it will shift the hour!
t.tm_isdst = 0;
t.tm_hour = 12;
t.tm_min = 0;
t.tm_sec = 0;
mktime(&t);
// Now we can add the interval
t.tm_year += y;
t.tm_mon += m;
t.tm_mday += d;
mktime(&t);
// Now reset the mid-day time values
t.tm_hour = hour;
t.tm_min = min;
t.tm_sec = sec;
// Return struct tm while keeping mid-day time the same
// while the only values that changed are the date and perhaps isdst.
return t;
}