Reputation:
In my code I have:
struct timeval arrival_time, struct timeval pickup_time;
sprintf(buf, "Stat-Req-Dispatch:: %lu.%06d\r\n", (pickup_time.tv_sec - arrival_time.tv_sec),
(pickup_time.tv_usec - arrival_time.tv_usec));
But I have noticed that this code isn't correct since sometimes the part which comes after .
in printing might be negative.
I tried: struct timeval dispatch_time = pickup_time-arrival_time;
but doesn't compile.
How can I properly print the difference between both times?
if (pickup_time.tv_usec < arrival_time.tv_usec)
{
dispatch_time.tv_sec = pickup_time.tv_sec - arrival_time.tv_sec - 1;
dispatch_time.tv_usec = pickup_time.tv_usec - arrival_time.tv_usec + 1000000;
} else
{
dispatch_time.tv_sec = pickup_time.tv_sec - arrival_time.tv_sec;
dispatch_time.tv_usec = pickup_time.tv_usec - arrival_time.tv_usec;
}
sprintf(buf, "%sStat-Req-Dispatch:: %lu.%06d\r\n", buf, dispatch_time.tv_sec, dispatch_time.tv_usec);
Upvotes: 2
Views: 4326
Reputation: 595711
timeval::tv_sec
is represented as seconds, and timeval::tv_usec
is represented as microseconds. Since you are just looking at the fields indivudally, pickup_time
may have a higher tv_sec
than arrival_time
, but have a lesser tv_usec
(ie, arrival_time
could be 1 second 30 microseconds while pickup_time
is 5 seconds 10 microseconds);
The GNU C documentation describes a timeval_subtract()
function that accounts for this:
The GNU C Library does not provide any functions for computing the difference between two values of type struct timeval or struct timespec. Here is the recommended way to do this calculation by hand. It works even on some peculiar operating systems where the tv_sec member has an unsigned type.
/* Subtract the ‘struct timeval’ values X and Y, storing the result in RESULT. Return 1 if the difference is negative, otherwise 0. */ int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) { /* Perform the carry for the later subtraction by updating y. */ if (x->tv_usec < y->tv_usec) { int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; y->tv_usec -= 1000000 * nsec; y->tv_sec += nsec; } if (x->tv_usec - y->tv_usec > 1000000) { int nsec = (x->tv_usec - y->tv_usec) / 1000000; y->tv_usec += 1000000 * nsec; y->tv_sec -= nsec; } /* Compute the time remaining to wait. tv_usec is certainly positive. */ result->tv_sec = x->tv_sec - y->tv_sec; result->tv_usec = x->tv_usec - y->tv_usec; /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; }
For example:
struct timeval arrival_time, pickup_time, elapsed_time;
...
timeval_subtract(&elapsed_time, &pickup_time, &arrival_time);
sprintf(buf, "Stat-Req-Dispatch:: %lu.%06d\r\n", elapsed_time.tv_sec, elapsed_time.tv_usec);
Upvotes: 0
Reputation: 52334
If you're using Linux+glibc, or a BSD OS, they give you some macros to manipulate timeval
s, including one to calculate the difference between two times:
#include <stdio.h>
#include <sys/time.h>
int main(void)
{
struct timeval arrival_time = { .tv_sec = 100, .tv_usec = 50 },
pickup_time = { .tv_sec = 150, .tv_usec = 0 },
time_difference;
timersub(&pickup_time, &arrival_time, &time_difference);
printf("%ld seconds %ld useconds\n", (long)time_difference.tv_sec,
(long)time_difference.tv_usec);
return 0;
}
Upvotes: 5