Рассчитать разницу между двумя временами в два разных дня

Я пытаюсь определить разницу во времени между двумя временами, которые я представляю как целые числа без знака (в структуре) следующим образом:

unsigned int day;
unsigned int month;
unsigned int year;

unsigned int hour;
unsigned int mins;
unsigned int seconds;

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

time1 = hours*3600 + mins*60 +  seconds;
time1 = hours2*3600 + mins2*60 +  seconds2;

    //time2 will always be less than time1

    time_diff_secs = time1_secs - time2_secs;
    time_diff_mins = time_diff_secs / 60;
    time_diff_secs = time_diff_secs % 60;

это производит этот вывод:

Time mayday was issued: 13 Hours 4 Mins 0 Seconds 
Time mayday was recieved: 13 Hours 10 Mins 0 Seconds 
Time between sending and receiving:  6.00Mins

что правильно, но когда у меня есть два раза в разные дни, я получаю это в результате:

Time mayday was issued: 23 Hours 0 Mins 0 Seconds 
Time mayday was recieved: 0 Hours 39 Mins 38 Seconds 
Time between sending and receiving: 71581448.00Mins 

Это явно неверно, я не знаю, как двигаться дальше, фактический результат должен быть 40 минут, а не 71,5 миллиона.


person chris edwards    schedule 03.12.2013    source источник


Ответы (3)


Вы получаете недолив. Попробуйте это (работает независимо от того, являются ли переменные signed или unsigned):

if (time1_secs < time2_secs) {
    // New day. Add 24 hours:
    time_diff_secs = 24*60*60 + time1_secs - time2_secs;
} else {
    time_diff_secs = time1_secs - time2_secs;
}

time_diff_mins = time_diff_secs / 60;
time_diff_secs = time_diff_secs % 60;
person Klas Lindbäck    schedule 03.12.2013

Другой способ сделать это, используя стандартную библиотеку C, единственное преимущество этого заключается в том, что вам не нужно беспокоиться о том, что ваши даты перекрывают годы, или о проблемах с перекрывающимися границами месяцев + ерунда високосного года:

unsigned int day;
unsigned int month;
unsigned int year;

unsigned int hour;
unsigned int mins;
unsigned int seconds;


time_t conv(void)
{
   time_t retval=0;
   struct tm tm;
   tm.tm_mday=day;
   tm.tm_mon=month -1;
   tm.tm_year=year - 1900;
   tm.tm_hour=hour;
   tm.tm_min=mins;
   tm.tm_sec=seconds;
   tm.tm_isdst=-1;
   retval=mktime(&tm);
   return retval;
}

int main()
{
   time_t start=0;
   time_t end=0;
   time_t diff=0;
   // assign day, month, year ... for date1
   start=conv();
   // assign day, month, year ... for date2
   end=conv();
   if(start>end)
     diff=start - end;
   else
     diff=end - start;
   printf("seconds difference = %ld\n", diff);
   return 0; 
}
person jim mcnamara    schedule 03.12.2013
comment
Хороший. Если время (YMDHMS) находится в местном времени, это способ сделать это. Если время UTC, необходима другая работа. ОП не указал ни того, ни другого, но призывы к бедствию подразумевают такие организации, как Береговая охрана, которая использует UTC. - person chux - Reinstate Monica; 03.12.2013
comment
Спасибо за ответ, он был слишком продвинутым, чтобы сработать, но я был бы помечен за то, что не полностью понял, что происходит. - person chris edwards; 04.12.2013

Изменять

time_diff_secs = time1_secs - time2_secs;

to

time_diff_secs = abs(time1_secs - time2_secs) % 86400;

Это заставит его быть минимальной разницей во времени между обоими временами и будет работать, даже если вы добавите дни, месяцы и т. д. к расчету time_diff_secs.

person Guido    schedule 03.12.2013
comment
просто быстрый вопрос, почему% 86400? - person chris edwards; 04.12.2013
comment
Это количество секунд в сутках. 24 * 60 * 60 было бы менее загадочно, но я почему-то запомнил это число! - person Guido; 04.12.2013