My code is here:
func stringFromTimeInterval(interval:NSTimeInterval) -> NSString {
var ti = NSInteger(interval)
var ms = ti * 1000
var secon
SWIFT 3 Extension
I think this way is a easier to see where each piece comes from so you can more easily modify it to your needs
extension TimeInterval {
private var milliseconds: Int {
return Int((truncatingRemainder(dividingBy: 1)) * 1000)
}
private var seconds: Int {
return Int(self) % 60
}
private var minutes: Int {
return (Int(self) / 60 ) % 60
}
private var hours: Int {
return Int(self) / 3600
}
var stringTime: String {
if hours != 0 {
return "\(hours)h \(minutes)m \(seconds)s"
} else if minutes != 0 {
return "\(minutes)m \(seconds)s"
} else if milliseconds != 0 {
return "\(seconds)s \(milliseconds)ms"
} else {
return "\(seconds)s"
}
}
}
Swift 5. No ms and some conditional formatting (i.e. don't display hours if there are 0 hours).
extension TimeInterval{
func stringFromTimeInterval() -> String {
let time = NSInteger(self)
let seconds = time % 60
let minutes = (time / 60) % 60
let hours = (time / 3600)
var formatString = ""
if hours == 0 {
if(minutes < 10) {
formatString = "%2d:%0.2d"
}else {
formatString = "%0.2d:%0.2d"
}
return String(format: formatString,minutes,seconds)
}else {
formatString = "%2d:%0.2d:%0.2d"
return String(format: formatString,hours,minutes,seconds)
}
}
}
Swift 3 solution for iOS 8+, macOS 10.10+ if the zero-padding of the hours doesn't matter:
func stringFromTime(interval: TimeInterval) -> String {
let ms = Int(interval.truncatingRemainder(dividingBy: 1) * 1000)
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
return formatter.string(from: interval)! + ".\(ms)"
}
print(stringFromTime(interval: 12345.67)) // "3:25:45.670"
import Foundation
extension TimeInterval {
func toReadableString() -> String {
// Nanoseconds
let ns = Int((self.truncatingRemainder(dividingBy: 1)) * 1000000000) % 1000
// Microseconds
let us = Int((self.truncatingRemainder(dividingBy: 1)) * 1000000) % 1000
// Milliseconds
let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
// Seconds
let s = Int(self) % 60
// Minutes
let mn = (Int(self) / 60) % 60
// Hours
let hr = (Int(self) / 3600)
var readableStr = ""
if hr != 0 {
readableStr += String(format: "%0.2dhr ", hr)
}
if mn != 0 {
readableStr += String(format: "%0.2dmn ", mn)
}
if s != 0 {
readableStr += String(format: "%0.2ds ", s)
}
if ms != 0 {
readableStr += String(format: "%0.3dms ", ms)
}
if us != 0 {
readableStr += String(format: "%0.3dus ", us)
}
if ns != 0 {
readableStr += String(format: "%0.3dns", ns)
}
return readableStr
}
}
Here is slightly improved version of @maslovsa's, with Precision
input param:
import Foundation
extension TimeInterval {
enum Precision {
case hours, minutes, seconds, milliseconds
}
func toString(precision: Precision) -> String? {
guard self > 0 && self < Double.infinity else {
assertionFailure("wrong value")
return nil
}
let time = NSInteger(self)
let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
let seconds = time % 60
let minutes = (time / 60) % 60
let hours = (time / 3600)
switch precision {
case .hours:
return String(format: "%0.2d", hours)
case .minutes:
return String(format: "%0.2d:%0.2d", hours, minutes)
case .seconds:
return String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds)
case .milliseconds:
return String(format: "%0.2d:%0.2d:%0.2d.%0.3d", hours, minutes, seconds, ms)
}
}
}
and usage:
let time: TimeInterval = (60 * 60 * 8) + 60 * 24.18
let hours = time.toString(precision: .hours) // 08
let minutes = time.toString(precision: .minutes) // 08:24
let seconds = time.toString(precision: .seconds) // 08:24:10
let milliseconds = time.toString(precision: .milliseconds) // 08:24:10.799
Swift 4 (with Range check ~ without Crashes)
import Foundation
extension TimeInterval {
var stringValue: String {
guard self > 0 && self < Double.infinity else {
return "unknown"
}
let time = NSInteger(self)
let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
let seconds = time % 60
let minutes = (time / 60) % 60
let hours = (time / 3600)
return String(format: "%0.2d:%0.2d:%0.2d.%0.3d", hours, minutes, seconds, ms)
}
}