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?

Hamid Yusifli
  • 9,688
  • 2
  • 24
  • 48
Maxm007
  • 1,190
  • 2
  • 13
  • 21
  • you can #include "CAHostTimeBase.h" from CoreAudio Utility Classes see https://developer.apple.com/library/ios/qa/qa1643/_index.html – Ol Sen Mar 18 '15 at 08:50

3 Answers3

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));
}
Kevin Chen
  • 994
  • 8
  • 24
BadPirate
  • 25,802
  • 10
  • 92
  • 123
  • 8
    It looks like your experimentation resulted in the same solution arrived at by Apple's engineers. https://developer.apple.com/library/mac/qa/qa1398/_index.html – user371320 Mar 10 '12 at 01:20
  • Fwiw the latter appears to be for OSX. – JohnK Apr 25 '13 at 01: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 '13 at 12:04
  • In my test this function will not count when iOS is in sleep. See the accepted answer for this question:http://stackoverflow.com/questions/12488481/getting-ios-system-uptime-that-doesnt-pause-when-asleep – Tim Nov 28 '15 at 05: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];
malex
  • 9,874
  • 3
  • 56
  • 77
  • what do you mean by "completion time"? – Eddy Mar 07 '14 at 07:40
  • 1
    Sorry for misspell, "computation time". I mean that obj-c works a bit slowly than pure C-code. – malex Mar 07 '14 at 09: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 '14 at 09: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 '14 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)
}
wzso
  • 3,482
  • 5
  • 27
  • 48
  • 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 08 '22 at 11:54