c-如何计算两个时间段之间的差异



在我的代码中,我有:

struct timeval arrival_time, struct timeval pickup_time;
sprintf(buf, "Stat-Req-Dispatch:: %lu.%06drn", (pickup_time.tv_sec - arrival_time.tv_sec),
(pickup_time.tv_usec - arrival_time.tv_usec));

但我注意到这个代码是不正确的,因为有时打印中.之后的部分可能是负数。

我尝试过:struct timeval dispatch_time = pickup_time-arrival_time;,但没有编译。

如何正确打印两次之间的差异?


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.%06drn", buf, dispatch_time.tv_sec, dispatch_time.tv_usec);

如果您使用的是Linux+glibc或BSD操作系统,它们会为您提供一些宏来操作timeval,其中包括一个计算两次差的宏:

#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 usecondsn", (long)time_difference.tv_sec,
(long)time_difference.tv_usec);
return 0;
}

timeval::tv_sec表示为秒,timeval::tv_usec表示为微秒。由于您只是单独查看字段,pickup_time可能具有比arrival_time更高的tv_sec,但具有更小的tv_usec(即,arrival_time可能是1秒30微秒,而pickup_time是5秒10微秒(;

GNU C文档描述了一个timeval_subtract()函数,它解释了这一点:

21.3计算经过时间

GNU C库不提供任何函数来计算struct-timeval或struct-ttimespec类型的两个值之间的差。以下是手工计算的推荐方法。它甚至适用于一些特殊的操作系统,其中tv_sec成员具有无符号类型。

/* 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;
}

例如:

struct timeval arrival_time, pickup_time, elapsed_time;
...
timeval_subtract(&elapsed_time, &pickup_time, &arrival_time);
sprintf(buf, "Stat-Req-Dispatch:: %lu.%06drn", elapsed_time.tv_sec, elapsed_time.tv_usec);

最新更新