Getting System Startup Time in macOS

Article's main picture
  • #macOS

• 9 min read

Introduction

Uptime is the interval of time that your Mac has been running since it was last powered down or restarted. If your uptime is a long time interval, you've got a smooth-running machine that can't be beaten. If not, you probably restart your Mac to free of RAM or fix some glitches that happened.

Using the OS utilities

There are several ways of getting uptime of a Mac.

Finding Mac uptime using System Information

Just open up System Information on your Mac. We can find it in Spotlight or Launchpad. Open it from the Utilities folder in Applications or right from the menu bar. For the latter, click on the Apple icon, then press and hold the Option key to change About This Mac to System Information. Once in System Information, navigate to the Software section in the left sidebar. The last entry in the right panel, appropriately named Time since boot will tell us how long your Mac has been running.

Here is how it looks in the System Information window below:

Time since boot in System Information window
Time since boot in System Information window

Finding Mac uptime using Terminal

We can also launch the Terminal app on a Mac using any method of preference: Spotlight, Launchpad, Utilities folder, etc. When the Terminal window pops up, we just use the uptime command. If we type it out and hit return on the keyboard, the output will look like this:

Mac uptime command in Terminal
Mac uptime command in Terminal

As we can see above, uptime is the second entry, whose color is blue. With this command, we can also see the current system time (red), the number of Terminal windows that are open (yellow), and the system load averages for the last 1, 5, and 15 minutes, which is an indicator of how busy the system's resources are (magenta).

Finding Mac boot time using Terminal

The command who -b can give us a date and time corresponding to the same boot time. See the command result below.

Mac boot time command in Terminal
Mac boot time command in Terminal

We can see that the boot time date is correct. If we subtract the uptime command result from the current time, we will get the boot time. It works! To find out more about how to check both the uptime and boot time of a Mac, you can find more information at this link.

How to check reboot and shutdown histories of a Mac

We will use the last reboot and last shutdown commands. We type them out one after another, then press return on the keyboard. This will provide us with the dates and times of the last few reboots the machine has gone through. The former logs every time a Mac was rebooted, and the latter when it was shut down. These logs have a history from when macOS was first installed on a Mac, when the logs were first created. We just need to check out the wtmp begins date at the bottom of the logs.

We can see last reboot command output below.

Mac last reboot command in Terminal
Mac last reboot command in Terminal

Also, we can see last shutdown command result.

Mac last shutdown command in Terminal
Mac last shutdown command in Terminal

The recent restart/shutdown history covers macOS kernel panics — when a system detects a fatal error and shuts down — in addition to power on/off events that you initiated through the software or hardware button. To learn more about how to check Mac's reboot and shutdown histories, find more information at this link.

Implementing an app to get the up- and boot times

We will create a simple macOS application with an enabled Sandbox to show possible ways to get Mac uptime and boot time.

Getting the uptime with systemUptime of NSProcessInfo

To get the Mac uptime, we will use an approach based on the systemUptime property in the NSProcessInfo class. It provides the amount of time the system has been awake since the last time it was restarted. It looks like this:

func setupMacUptime() {
    let processInfo = ProcessInfo()
    let systemUptime = processInfo.systemUptime
        
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
        
    let infoString = formatter.string(from: systemUptime)
    infoLabel.stringValue = "Uptime: \(infoString)"
}

You can see the final result below. Source code for this approach is available here in the UptimeInfoViewController_1.swift file.

NSProcessInfo's systemUptime value in prototype
NSProcessInfo's systemUptime value in prototype

Getting the uptime with the POSIX timer

Another way to get a Mac uptime is to use POSIX clock_gettime() function that was implemented in iOS 10 and macOS 10.12. When used with the CLOCK_MONOTONIC argument, it does seem to return the uptime value. However, this is not guaranteed by the documentation:

For this clock, the value returned by clock_gettime() represents the amount of time (in seconds and nanoseconds) since an unspecified point in the past (for example, system start-up time or the Epoch). This point does not change after the system start-up time.

And an extract from the corresponding macOS page:

  • CLOCK_MONOTONIC clock that increments monotonically, tracking the time since an arbitrary point, and will continue to increment while the system is asleep.
  • CLOCK_MONOTONIC_RAW clock that increments monotonically, tracking the time since an arbitrary point like CLOCK_MONOTONIC. However, this clock is unaffected by frequency or time adjustments. It should not be compared to other system time sources.
  • CLOCK_MONOTONIC_RAW_APPROX like CLOCK_MONOTONIC_RAW, but reads a value cached by the system at context switch. This can be read faster but at a loss of accuracy as it may return values that are milliseconds old.
  • CLOCK_UPTIME_RAW clock that increments monotonically, in the same manner as CLOCK_MONOTONIC_RAW, but that does not increment while the system is asleep. The returned value is identical to the result of mach_absolute_time() after the appropriate mach_timebase conversion is applied.

Nice, let's start coding!

var macUptime: timespec {
    var uptime = timespec()
    if 0 != clock_gettime(CLOCK_MONOTONIC_RAW, &uptime) {
        fatalError("Could not execute clock_gettime, errno: \(errno)")
    }
    
    return uptime
}
    
func setupMacUptime() {
    let uptime = TimeInterval(macUptime.tv_sec)
        
    let formatter = DateComponentsFormatter()
    formatter.unitsStyle = .full
        
    let infoString = formatter.string(from: uptime)
    infoLabel.stringValue = "Uptime: \(infoString)"
}

You can see the final result below. The source code for this approach is available here in the UptimeInfoViewController_2.swift file.

POSIX timer's macUptime value in prototype
POSIX timer's macUptime value in prototype

Getting the boot time with the sysctl utility

Now, if we want to get Mac boot time, we can use the kernel's boot time with sysctl utility for this task. The sysctl utility retrieves the kernel state and allows processes with appropriate privileges to set the kernel state. Look at the code below.

var kernelBootTime: timeval {
    var mib = [CTL_KERN, KERN_BOOTTIME]
    var bootTime = timeval()
    var bootTimeSize = MemoryLayout<timeval>.size

    if 0 != sysctl(&mib, UInt32(mib.count), &bootTime, &bootTimeSize, nil, 0) {
        fatalError("Could not get boot time, errno: \(errno)")
    }
        
    return bootTime
}
    
func setupMacBootTime() {
    let bootTime = kernelBootTime
    let kernelBootTimeDate = Date(timeIntervalSince1970: TimeInterval(bootTime.tv_sec) + TimeInterval(bootTime.tv_usec) / 1_000_000)
        
    let formatter = DateFormatter()
    formatter.dateStyle = .long
    formatter.timeStyle = .long
        
    let infoString = formatter.string(from: kernelBootTimeDate)
    infoLabel.stringValue = "Boot Date: \(infoString)"
}

You can see the final result below. The source code for this approach is available here in the BootTimeInfoViewController_1.swift file.

sysctl utility's kernelBootTime value in prototype
sysctl utility's kernelBootTime value in prototype

How to programmatically restart, shutdown and logout from a Mac

A simple way to do this is via an inline AppleScript It will work in Sandbox if an application has the correct entitlements. The application can do all of the above by sending specific Apple events to the loginwindow process. This process will interpret the Apple events and cause the requested event.

Conclusion

To sum up, we have different approaches to getting Mac startup time:

  • The uptime command gives us the current time, followed by the time interval the system has been running.
  • The who -b command gives us a date and time corresponding to the same boot time.
  • The last reboot command uses the /var/log/wtmp file to determine the last boot. This log file has been rotated since the last boot took place, so it doesn't contain information about the last boot.

To get Mac uptime and boot time programmatically, we can use the following:

  • systemUptime property from NSProcessInfo
  • POSIX’s timer (clock_gettime() function)
  • sysctl utility (kernel boot time)

More From research

Subscribe to our newsletter