Search code examples
objective-ciosmacostimeuptime

Get the precise time of system bootup on iOS/OS X


Is there an API to obtain the NSDate or NSTimeInterval representing the time the system booted? Some APIs such as [NSProcessInfo systemUptime] and Core Motion return time since boot. I need to precisely correlate these uptime values with NSDates, to about a millisecond.

Time since boot ostensibly provides more precision, but it's easy to see that NSDate already provides precision on the order of 100 nanoseconds, and anything under a microsecond is just measuring interrupt latency and PCB clock jitter.

The obvious thing is to subtract the uptime from the current time [NSDate date]. But that assumes that time does not change between the two system calls, which is, well, hard to accomplish. Moreover if the thread is preempted between the calls, everything is thrown off. The workaround is to repeat the process several times and use the smallest result, but yuck.

NSDate must have a master offset it uses to generate objects with the current time from the system uptime, is there really no way to obtain it?


Solution

  • In OSX you could use sysctl(). This is how the OSX Unix utility uptime does it. Source code is available - search for boottime.

    Fair warning though, in iOS i have no idea if this would work.

    UPDATE: found some code :)

    #include <sys/types.h>
    #include <sys/sysctl.h>  
    
    #define MIB_SIZE 2  
    
    int mib[MIB_SIZE];
    size_t size;
    struct timeval  boottime;
    
    mib[0] = CTL_KERN;
    mib[1] = KERN_BOOTTIME;
    size = sizeof(boottime);
    if (sysctl(mib, MIB_SIZE, &boottime, &size, NULL, 0) != -1)
    {
        // successful call
        NSDate* bootDate = [NSDate dateWithTimeIntervalSince1970:
                                   boottime.tv_sec + boottime.tv_usec / 1.e6];
    }
    

    see if this works...