Другие ответы приводят к крайне нестабильным результатам в зависимости от того, как ваша система инициализирует struct tm и правильно ли инициализированы значения времени в полдень.
Если все, что вас интересует, это изменения даты, а время остается неизменным, тогда установите tm_isdst
, tm_hour
, tm_sec
все на 0, прежде чем переходить к 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;
}
Хотелось бы, чтобы это было проще, но так оно и должно быть.