I am trying to determine the time difference between two times, which i represent as unsigned integers (in a sturct) as follows:
unsigned int day;
unsigned int month;
unsigned int year;
unsigned int hour;
unsigned int mins;
unsigned int seconds;
i can work out the time difference in minutes between two times that occur on the same day easily enough using: This isn't my exact code, this is just the logic behind it.
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;
this produces this output:
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
which is correct, but when I have two times that are on different days I get this as the result:
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
This is obviously incorrect, I am not sure how to progress from here, the actual result should be 40mins, not 71.5million.
You are getting an underflow. Try this (works regardless of whether the variables are signed
or 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;
Another way to do it using the standard C library, the only advantage of this is you do not have to worry about your dates overlapping years, or problems with overlapping month boundaries + leap year nonsense:
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;
}
Change
time_diff_secs = time1_secs - time2_secs;
to
time_diff_secs = abs(time1_secs - time2_secs) % 86400;
This will force it to be the minimum time difference between both times and will work even if you add days, months, etcetera to the time_diff_secs
calculation.