22.3 Calculating Elapsed Time

Often, one wishes to calculate an elapsed time as the difference between two simple calendar times. The GNU C Library provides only one function for this purpose.

Function: double difftime (time_t end, time_t begin)

Preliminary: | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

The difftime function returns the number of seconds of elapsed time from calendar time begin to calendar time end, as a value of type double.

On POSIX-conformant systems, the advantage of using ‘difftime (end, begin)’ over ‘end - begin’ is that it will not overflow even if end and begin are so far apart that a simple subtraction would overflow. However, if they are so far apart that a double cannot exactly represent the difference, the result will be inexact.

On other systems, time_t values might be encoded in a way that prevents subtraction from working directly, and then difftime would be the only way to compute their difference.

The GNU C Library does not provide any functions for computing the difference between two values of type struct timespec or struct timeval. Here is one way to do this calculation by hand. It works even on peculiar operating systems where the tv_sec member has an unsigned type.

#include <stdckdint.h>
#include <time.h>

/* Put into *R the difference between X and Y.
   Return true if overflow occurs, false otherwise. */

bool
timespec_subtract (struct timespec *r,
                   struct timespec x, struct timespec y)
{
  /* Compute nanoseconds, setting borrow to 1 or 0
     for propagation into seconds. */
  long int nsec_diff = x.tv_nsec - y.tv_nsec;
  bool borrow = nsec_diff < 0;
  r->tv_nsec = nsec_diff + 1000000000 * borrow;

  /* Compute seconds, returning true if this overflows. */
  bool v = ckd_sub (&r->tv_sec, x.tv_sec, y.tv_sec);
  return v ^ ckd_sub (&r->tv_sec, r->tv_sec, borrow);
}