14

struct timeval represents and instant in time with two members, tv_sec (seconds) and tv_usec (microseconds). In this representation, tv_usec is not by itself an absolute time it is a sub second offset off of tv_sec.

struct timespec works the same way except that instead of microseconds it's offset (tv_nsec) is stored in nanosecond units.

The question is: Is there a standard way to convert between these two?

dicroce
  • 42,886
  • 27
  • 97
  • 139

2 Answers2

17

In sys/time.h there are two macros that do what you want:

TIMEVAL_TO_TIMESPEC(X, Y)

and

TIMESPEC_TO_TIMEVAL(X, Y)

See the docs here: http://www.daemon-systems.org/man/TIMEVAL_TO_TIMESPEC.3.html

Craig McQueen
  • 39,646
  • 28
  • 118
  • 178
CommanderHK
  • 1,108
  • 11
  • 7
  • On Linux you may need to define `_GNU_SOURCE` before the `#include `, in order to get these macros. – Craig McQueen May 28 '15 at 05:26
  • Note TIMESPEC_TO_TIMEVAL truncates the tv_nsec value, which may not be desired. I.e. you may prefer to round up. This is required for example if passing a timeval to setitimer(), as if a timespec was truncated to zero, the timer would be cleared rather than being set to the min value (of a microsecond) – pixelbeat Nov 09 '20 at 00:14
16

Looking at this doc, I would think multiplying tv_usec by 1000 is sufficient to get tv_nsec.

More important, I suspect is the source of the different structures: they could be filled by different clocks.

kdgregory
  • 37,714
  • 10
  • 75
  • 100
  • Since tv_nsec is a sub second offset, what if the multiplication by 1000 results in a value greater than 1 billion... Wouldn't you then need to add 1 to tv_sec and then set tv_nsec to the amount over 1 billion? – dicroce Oct 24 '09 at 16:44
  • 9
    No because `tv_usec`, being an offset in microseconds, is guaranteed to be smaller than 1 million, so multiplying it by 1000 gives a value less than 1 billion. – JaakkoK Oct 24 '09 at 16:53
  • 1
    And if you want to go from a timespec to a timeval, you'd divide `tv_nsec` by 1000 to get `tv_usec` (possibly adding 500 first, to round up). –  Oct 26 '15 at 02:39