My code is here:
func stringFromTimeInterval(interval:NSTimeInterval) -> NSString {
var ti = NSInteger(interval)
var ms = ti * 1000
var secon
Swift 4:
extension TimeInterval{
func stringFromTimeInterval() -> String {
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)
}
}
Use:
self.timeLabel.text = player.duration.stringFromTimeInterval()
Swift 4, without using the .remainder
(which returns wrong values):
func stringFromTimeInterval(interval: Double) -> NSString {
let hours = (Int(interval) / 3600)
let minutes = Int(interval / 60) - Int(hours * 60)
let seconds = Int(interval) - (Int(interval / 60) * 60)
return NSString(format: "%0.2d:%0.2d:%0.2d",hours,minutes,seconds)
}
You can use Measurement
and UnitDuration
to convert a TimeInterval
value into any duration unit. To see milliseconds in the result you need UnitDuration.milliseconds
that requires iOS 13.0, tvOS 13.0, watchOS 6.0 or macOS 10.15. I put all actions that should be done in func convertDurationUnitValueToOtherUnits(durationValue:durationUnit:smallestUnitDuration:)
(Swift 5.1.3/Xcode 11.3.1):
import Foundation
@available(iOS 10.0, tvOS 10.0, watchOS 3.0, macOS 10.12, *)
func convert<MeasurementType: BinaryInteger>(
measurementValue: Double, unitDuration: UnitDuration, smallestUnitDuration: UnitDuration
) -> (MeasurementType, Double) {
let measurementSmallest = Measurement(
value: measurementValue,
unit: smallestUnitDuration
)
let measurementSmallestValue = MeasurementType(measurementSmallest.converted(to: unitDuration).value)
let measurementCurrentUnit = Measurement(
value: Double(measurementSmallestValue),
unit: unitDuration
)
let currentUnitCount = measurementCurrentUnit.converted(to: smallestUnitDuration).value
return (measurementSmallestValue, measurementValue - currentUnitCount)
}
@available(iOS 10.0, tvOS 10.0, watchOS 3.0, macOS 10.12, *)
func convertDurationUnitValueToOtherUnits<MeasurementType: BinaryInteger>(
durationValue: Double,
durationUnit: UnitDuration,
smallestUnitDuration: UnitDuration
) -> [MeasurementType] {
let basicDurationUnits: [UnitDuration] = [.hours, .minutes, .seconds]
let additionalDurationUnits: [UnitDuration]
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
additionalDurationUnits = [.milliseconds, .microseconds, .nanoseconds, .picoseconds]
} else {
additionalDurationUnits = []
}
let allDurationUnits = basicDurationUnits + additionalDurationUnits
return sequence(
first: (
convert(
measurementValue: Measurement(
value: durationValue,
unit: durationUnit
).converted(to: smallestUnitDuration).value,
unitDuration: allDurationUnits[0],
smallestUnitDuration: smallestUnitDuration
),
0
)
) {
if allDurationUnits[$0.1] == smallestUnitDuration || allDurationUnits.count <= $0.1 + 1 {
return nil
} else {
return (
convert(
measurementValue: $0.0.1,
unitDuration: allDurationUnits[$0.1 + 1],
smallestUnitDuration: smallestUnitDuration
),
$0.1 + 1
)
}
}.compactMap { $0.0.0 }
}
This is how you can call it:
let intervalToConvert: TimeInterval = 12345.67
let result: [Int] = convertDurationUnitValueToOtherUnits(
durationValue: intervalToConvert,
durationUnit: .seconds,
smallestUnitDuration: .milliseconds
)
print("\(result[0]) hours, \(result[1]) minutes, \(result[2]) seconds, \(result[3]) milliseconds") // 3 hours, 25 minutes, 45 seconds, 670 milliseconds
As you can see I did not use numeric constants like 60 and 1000 to get the result.
Equivalent in Objective-C, based on the @matthias-bauch answer.
+ (NSString *)stringFromTimeInterval:(NSTimeInterval)timeInterval
{
NSInteger interval = timeInterval;
NSInteger ms = (fmod(timeInterval, 1) * 1000);
long seconds = interval % 60;
long minutes = (interval / 60) % 60;
long hours = (interval / 3600);
return [NSString stringWithFormat:@"%0.2ld:%0.2ld:%0.2ld,%0.3ld", hours, minutes, seconds, (long)ms];
}
for convert hour and minutes to seconds in swift 2.0:
///RETORNA TOTAL DE SEGUNDOS DE HORA:MINUTOS
func horasMinutosToSeconds (HoraMinutos:String) -> Int {
let formatar = NSDateFormatter()
let calendar = NSCalendar.currentCalendar()
formatar.locale = NSLocale.currentLocale()
formatar.dateFormat = "HH:mm"
let Inicio = formatar.dateFromString(HoraMinutos)
let comp = calendar.components([NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: Inicio!)
let hora = comp.hour
let minute = comp.minute
let hours = hora*3600
let minuts = minute*60
let totseconds = hours+minuts
return totseconds
}
converted into an swift 2 extension + variable format :
extension NSTimeInterval {
func timeIntervalAsString(format format : String = "hh:mm:ss:sss") -> String {
let ms = Int((self % 1) * 1000)
let asInt = NSInteger(self)
let s = asInt % 60
let m = (asInt / 60) % 60
let h = (asInt / 3600)
var value = format
value = value.replace("hh", replacement: String(format: "%0.2d", h))
value = value.replace("mm", replacement: String(format: "%0.2d", m))
value = value.replace("sss", replacement: String(format: "%0.3d", ms))
value = value.replace("ss", replacement: String(format: "%0.2d", s))
return value
}
}
extension String {
/**
Replaces all occurances from string with replacement
*/
public func replace(string:String, replacement:String) -> String {
return self.stringByReplacingOccurrencesOfString(string, withString: replacement, options: NSStringCompareOptions.LiteralSearch, range: nil)
}
}