10
\$\begingroup\$

Simply put, is this function a correct and safe way to add and/or subtract time to a tm struct (from <time.h>)?

void AddTime(int seconds, tm *date)
{
    date->tm_sec += seconds;
    mktime(date);
}

seconds could be any value, supposedly larger than 60 (or smaller than -60). I'm using mktime to readjust the other values in tm, but I don't know if that's right.

I'm also not taking into account going below 1970 or above 3001 for the year, which I think are the default bounds for mktime to operate. I can check for that elsewhere.

\$\endgroup\$

3 Answers 3

5
\$\begingroup\$

I would add a sanity check on the pointer as well:

void AddTime(int seconds, tm* date) {
    if (date == NULL) return;
    date->tm_sec += seconds;
    mktime(date);
}

But other than that it looks correct.

Reading some documentation on mktime, this appears to be what it was meant for.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Your code example will not compile as is. struct tm *date will help with that. \$\endgroup\$
    – ryyker
    Dec 19, 2017 at 16:09
5
\$\begingroup\$

This may be unrelated to your application, but it should be noted that you haven't mentioned the size of int for your system. For a 16-bit system (very common on micro controllers) your function will only be valid in the range of -32768 to 32767.

You also need to take into account that the value date.tm_min can already be in the range of 0-59, so you that makes the new range -32768 to (32767-59).

I mention this because 32767 seconds corresponds to roughly 9 hours, which may not be enough for your application.

You can convert the tm structure to seconds using time_t values generated with mktime, do your subtraction, then convert back to tm with gmtime(). Be careful to make sure you use the correct starting year (1900 and 1970 are the usual ones). Also, be aware of the 2038 overflow for 32 bit time_t.

\$\endgroup\$
1
  • \$\begingroup\$ You are absolutely right, thanks for the correction. \$\endgroup\$ Jun 8, 2017 at 1:36
-2
\$\begingroup\$

You should put more validations. For example, if you add more than 60 seconds, you need to increment minutes too. If the minutes value is 59, you must increment hours too.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I thought mktime distributed the overflows accordingly. Does it not? \$\endgroup\$
    – MPelletier
    Nov 29, 2012 at 13:59
  • 4
    \$\begingroup\$ mktime does perform normalization on its values \$\endgroup\$
    – seand
    Nov 29, 2012 at 16:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.