user788171
user788171

Reputation: 17553

C++ time(NULL) gives inconsistent results

I have the following function to get the seconds since epoch for midnight of the present day.

long int midnight_time()
{
  time_t t;
  struct tm *local;
  t = time(NULL);
  struct tm timeinfo;
  local = localtime(&t);
  timeinfo.tm_year = local->tm_year;
  timeinfo.tm_mon = local->tm_mon;
  timeinfo.tm_mday = local->tm_mday;
  timeinfo.tm_hour = 0;
  timeinfo.tm_min=0;
  timeinfo.tm_sec=0;
  long int midnight_epoch = mktime(&timeinfo);
  return midnight_epoch;
}

When I called this function twice in code right after each other, e.g.

cout<<midnight_time()<<endl;
cout<<midnight_time()<<endl;

I consistently get radically different results, for example: 1367816400 1367812800

This is a difference of nearly 4000 seconds. I would expect the numbers to be the same. Can anybody see what I am doing wrong?

Upvotes: 2

Views: 571

Answers (3)

freitass
freitass

Reputation: 6694

To avoid problems caused by uninitialized memory locations (which seems to be your case), you should use the tm structure to which a pointer is returned by the localtime function. Here is an example:

time_t midnight_time()
{
  struct tm *local;
  time_t now = time(NULL);
  local = localtime(&now);

  local->tm_hour = 0;
  local->tm_min=0;
  local->tm_sec=0;

  return mktime(local);
}

@jmihalicza better answers your question, this is just a suggestion to improve your code.

Upvotes: 2

Mark B
Mark B

Reputation: 96233

The problem, as alluded to in @jmihalicza answer, is that you don't set the tm_isdst flag from the local struct. Presumably since your times are different by an hour the flag is opposite in your two structs one of the two times, causing the mktime to generate a time one hour different.

Instead of using mktime however, you might find it easier to simply back out the hours, minutes, and seconds (although this won't work well during DST transitions - I can't tell from your question if that's a factor for you):

return t - (timeinfo.tm_hour * 3600) - (timeinfo.tm_min * 60) - timeinfo.tm_sec;

Upvotes: 1

jmihalicza
jmihalicza

Reputation: 2089

Isn't it that the tm_isdst flag is left unset? The difference is exactly 1 hour.

Upvotes: 6

Related Questions