Question

I am trying to get the difference between two date by using below C code.

but code always giving difference 0. Help me to where i am making mistake.

I am using gcc compiler under linux.

#include <stdio.h>  
#include <time.h>       
int main ()
{
  struct tm start_date;
  struct tm end_date;
  time_t start_time, end_time;
  double seconds;

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 2013;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 2013;

  start_time = mktime(&start_date);
  end_time = mktime(&end_date);

  seconds = difftime(end_time, start_time);

  printf ("%.f seconds difference\n", seconds);

  return 0;
}

EDIT : @qchen answer helped lot to solve my problem. one more doubt is there. Below was my update. From the answer

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10-1; start_date.tm_mday = 18; start_date.tm_year = 2013-1876;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10-1; end_date.tm_mday = 20; end_date.tm_year = 2013-1876;

tm_year is the year since 1900, then why i getting correct output if i replace 1876 with year between 1876 to 2012.

Was it helpful?

Solution

The problem is that tm_year is the year since 1900, so 2013 would be 113 http://en.cppreference.com/w/cpp/chrono/c/tm

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 113;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 113;

Given 2013, mktime will return -1 as the calendar time cannot be represented. You would think that the year 3913 would be a valid calendar time and the reason is related to the year 2038 problem, as pointed out by Joni

OTHER TIPS

OP did not check mktime()` result.

As @Joni mentions, set the tm_isdst field. Use 0 or 1 if you know if how DST is applied, else use '-1' and let the OS make the determination.

@qchen mentioned the year 1900 offset as you likely want .tm_year = 2013-1900.

I assert the underlying issue is using mktime() without checcking if it is (time_t) -1. With robust code, this return value should be tested and missing that opened OP code to unexpected results.

In addition to not specifying the year correctly, you are leaving the tm_isdst field unset. mktime uses this field to determine if the date has or doesn't have daylight-savings time in effect, or if the DST setting should be looked up from timezone databases. This can make the result off by one hour. Add these lines:

/* lookup if DST or not */
start_date.tm_isdst = -1;
end_date.tm_isdst = -1;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top