Is there a good way to translate timespec into NSDate

My new EndpointSecurity client code receives event messages of type esmessaget. These contain 3 time values.

Code Block
struct timespec time;
uint64_t mach_time;
uint64_t deadline;

To interpret the deadline I refer to the mach_time. However, when I wish to log/formet/otherwise-consider the "wall time" where the event was created - I need to translate the timespec into NSDate (hmm... NSTimeInterval?) and I fail to find any documentation or hint about the right way to do so.

What I tried so far looks like this:

Code Block
NSDate * timestamp = [NSDate dateWithTimeIntervalSince1970:(double)(message->time.tv_sec) + (double)(message->time.tv_sec) / 1E9 ];

which at least mathematically seems reasonable, but I'm not sure this is the right answer, and I don't know anything about the behaviour of timespec, its origin and accuracy, and whether or not it is consistent.

Can anyone shed a little light on the relation between these two time formats?

Thanks!
Answered by DTS Engineer in 672597022
OK, let’s split this up by time type.



Mach absolute time counts in abstract time units. You can get information about this time base using mach_timebase_info. However, there are nicer APIs that can help with this. I listed some of them in QA1398 Mach Absolute Time Units but I’m sure that there are other, more-modern alternatives. Indeed, looking in <dispatch/time.h> I see that it defines an equivalence between dispatch_time_t and Mach absolute time.

Jack_Martin wrote:

what about

float time_left = (msg->deadline * 1.f - mach_absolute_time()) / NSEC_PER_SEC; // seconds

Do not do this. Mach absolute time does not count in nanoseconds on all platforms (IIRC it does on Intel but did not on PowerPC and does not on Apple silicon). Rather, use the time returned by mach_timebase_info or some higher-level API.



A timespec consists of two fields:
  • tv_sec, which is a count of seconds from the start of 1970.

  • tv_nsec, which is the fractional second counter in nanoseconds.

The code you posted is a reasonable way to convent from this to an NSDate.

A timespec is the higher-precision equivalent of a timeval, and the tv_sec field has the same semantics. It corresponds to ‘wall’ time and thus can change if the machine’s clock changes.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
what about

float time_left = (msg->deadline * 1.f - mach_absolute_time()) / NSEC_PER_SEC; // seconds


Accepted Answer
OK, let’s split this up by time type.



Mach absolute time counts in abstract time units. You can get information about this time base using mach_timebase_info. However, there are nicer APIs that can help with this. I listed some of them in QA1398 Mach Absolute Time Units but I’m sure that there are other, more-modern alternatives. Indeed, looking in <dispatch/time.h> I see that it defines an equivalence between dispatch_time_t and Mach absolute time.

Jack_Martin wrote:

what about

float time_left = (msg->deadline * 1.f - mach_absolute_time()) / NSEC_PER_SEC; // seconds

Do not do this. Mach absolute time does not count in nanoseconds on all platforms (IIRC it does on Intel but did not on PowerPC and does not on Apple silicon). Rather, use the time returned by mach_timebase_info or some higher-level API.



A timespec consists of two fields:
  • tv_sec, which is a count of seconds from the start of 1970.

  • tv_nsec, which is the fractional second counter in nanoseconds.

The code you posted is a reasonable way to convent from this to an NSDate.

A timespec is the higher-precision equivalent of a timeval, and the tv_sec field has the same semantics. It corresponds to ‘wall’ time and thus can change if the machine’s clock changes.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Is there a good way to translate timespec into NSDate
 
 
Q