37

I use this code to keep track of last reboot:

+ (float) secondsSinceLastReboot{
     return ((float)(mach_absolute_time())) * ((float)timebase.numer) / ((float)timebase.denom) / 1000000000.0f;
}

I assumed mach_absolute_time() was based on last device boot time like it is on a mac. It doesn't seem to be based on that. I actually have no idea what it is based on.

Look at the following behaviour (today's date is 2009-09-20):

lastRebootTime = [[NSDate date] addTimeInterval:-[self secondsSinceLastReboot]];
//last Reboot Time will contain : 2009-09-20 07:42:14 +0100

I'm absolutely certain I did not reboot my device at that time. My device hasn't been booted in a week.

Furthermore, when I unhook my device from the cable and run this app , it seems that when the device goes to sleep, the lastRebootTime starts shifting in the future. It seems mach_absolute_time doesn't keep account for sleep time. Or am i wrong about this?

I would really like to be able to get a timestamp from when the device last rebooted. Any idea's?

1

3 Answers 3

56

Had some trouble with this myself. There isn't a lot of good documentation, so I went with experimentation. Here's what I was able to determine:

mach_absolute_time depends on the processor of the device. It returns ticks since the device was last rebooted (otherwise known as uptime). In order to get it in a human readable form, you have to modify it by the result from mach_timebase_info (a ratio), which will return billionth of seconds (or nanoseconds). To make this more usable I use a function like the one below:

#include <mach/mach_time.h>

int getUptimeInMilliseconds()
{
    const int64_t kOneMillion = 1000 * 1000;
    static mach_timebase_info_data_t s_timebase_info;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        (void) mach_timebase_info(&s_timebase_info);
    });

    // mach_absolute_time() returns billionth of seconds,
    // so divide by one million to get milliseconds
    return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
4
  • 9
    It looks like your experimentation resulted in the same solution arrived at by Apple's engineers. developer.apple.com/library/mac/qa/qa1398/_index.html
    – user371320
    Mar 10, 2012 at 1:20
  • Fwiw the latter appears to be for OSX.
    – JohnK
    Apr 25, 2013 at 1:39
  • 4
    This function works incorrectly for iOS. In return string you make integer value calculation. Since on iPhone 5 s_timebase_info.numer = 125 and s_timebase_info.denom = 3 finally you can get the same uptime during about 40 seconds between requests. Multiply mach_absolute_time() by float 1.0 for correctness.
    – malex
    Dec 13, 2013 at 12:04
  • In my test this function will not count when iOS is in sleep. See the accepted answer for this question:stackoverflow.com/questions/12488481/…
    – Tim
    Nov 28, 2015 at 5:26
9

If you don't care a lot about computation time you can use simple Obj-C class from Foundation

NSTimeInterval systemUptime = [[NSProcessInfo processInfo] systemUptime];
4
  • what do you mean by "completion time"?
    – Eddy
    Mar 7, 2014 at 7:40
  • 1
    Sorry for misspell, "computation time". I mean that obj-c works a bit slowly than pure C-code.
    – malex
    Mar 7, 2014 at 9:40
  • i use this code for check this in simulator but can't get the difference, after restart the simulator both systemUptime same..
    – g212gs
    Mar 20, 2014 at 9:07
  • 2
    @g212gs Note that it is system uptime! simulator's system - OSX. So you get right answer - the same uptime until you reboot you mac
    – malex
    Mar 20, 2014 at 10:01
3

In case someone needs it in Swift (works in 4.2 & 5.0).

let beginTime = mach_absolute_time()

// do something...

var baseInfo = mach_timebase_info_data_t(numer: 0, denom: 0)
if mach_timebase_info(&baseInfo) == KERN_SUCCESS {
    let finiTime = mach_absolute_time()
    
    let nano = (finiTime - beginTime) * UInt64(baseInfo.numer) / UInt64(baseInfo.denom)
}
1
  • You can now use clock_gettime_nsec_np(CLOCK_UPTIME_RAW) to get the time in nanoseconds in one call. Also, if you want it including sleep time, you can use clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)
    – robinst
    Mar 8, 2022 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.