разница между двумя датами в C

Я пытаюсь получить разницу между двумя датами, используя приведенный ниже код C.

но код всегда дает разницу 0. Помогите мне, где я делаю ошибку.

Я использую компилятор gcc под 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 помог решить мою проблему. есть еще одно сомнение. Ниже было мое обновление. Из ответа

  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 - это год с 1900 года, тогда почему я получаю правильный результат, если заменяю 1876 годом между 1876 и 2012 годами.


person sujin    schedule 26.09.2013    source источник
comment
Я бы обнулил эти структуры, просто убедившись, что все поля равны нулю. Хотя, наверное, это не твоя проблема.   -  person Charlie Burns    schedule 26.09.2013
comment
Когда я запускаю его на macbook, я получаю «разницу в 428400 секунд». gcc и лязг.   -  person Charlie Burns    schedule 26.09.2013
comment
Я получаю разницу в 432000 секунд, когда обнуляю эти структуры. Так что есть некоторые поля в игре там.   -  person Charlie Burns    schedule 26.09.2013
comment
Запустив исходный код под valgrind, вы получите кучу предупреждений об использовании неинициализированных значений в mktime. Вы определенно должны обнулить структуры.   -  person Joni    schedule 26.09.2013
comment
Смотрите ответ Чукса ниже. Это единственное объяснение разницы в 0, которую вы видели. Вам нужно проверить возвращаемое значение mktime() на наличие ошибок.   -  person Charlie Burns    schedule 27.09.2013


Ответы (3)


Проблема в том, что tm_year — это год с 1900 года, поэтому 2013 год будет 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;

Учитывая 2013 год, mktime вернет -1, поскольку календарное время не может быть представлено. Вы могли бы подумать, что 3913 год будет правильным календарным временем, и причина связана с проблемой 2038 года, как указал Джони

person qxixp    schedule 26.09.2013

OP не проверил результат mktime()`.

Как упоминает @Joni, установите поле tm_isdst. Используйте 0 или 1, если вы знаете, как применяется летнее время, в противном случае используйте «-1» и позвольте ОС принять решение.

@qchen упомянул смещение 1900 года, поскольку вы, вероятно, хотите .tm_year = 2013-1900.

Я утверждаю, что основная проблема заключается в использовании mktime() без проверки, является ли это (time_t) -1. В надежном коде это возвращаемое значение должно быть проверено и пропущено, что открыло OP-код с неожиданными результатами.

person chux - Reinstate Monica    schedule 26.09.2013

Помимо неправильного указания года, вы оставляете поле tm_isdst неустановленным. mktime использует это поле, чтобы определить, действует ли для даты летнее время или нет, или нужно ли искать настройку летнего времени в базах данных часовых поясов. Это может уменьшить результат на один час. Добавьте эти строки:

/* lookup if DST or not */
start_date.tm_isdst = -1;
end_date.tm_isdst = -1;
person Joni    schedule 26.09.2013