Conversion from Nstimeinterval to Hour,Minutes,Seconds,Milliseconds in Swift

conversion from NSTimeInterval to hour,minutes,seconds,milliseconds in swift

Swift supports remainder calculations on floating-point numbers, so we can use % 1.

var ms = Int((interval % 1) * 1000)

as in:

func stringFromTimeInterval(interval: TimeInterval) -> NSString {

let ti = NSInteger(interval)

let ms = Int((interval % 1) * 1000)

let seconds = ti % 60
let minutes = (ti / 60) % 60
let hours = (ti / 3600)

return NSString(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
}

result:

stringFromTimeInterval(12345.67)                   "03:25:45.670"

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()

How to convert TimeInterval into Minutes, Seconds and Milliseconds in Swift

You can create a TimeInterval extension to format your elapsed time as follow:

Xcode 11.4 • Swift 5.2 or later

extension TimeInterval {
var hourMinuteSecondMS: String {
String(format:"%d:%02d:%02d.%03d", hour, minute, second, millisecond)
}
var minuteSecondMS: String {
String(format:"%d:%02d.%03d", minute, second, millisecond)
}
var hour: Int {
Int((self/3600).truncatingRemainder(dividingBy: 3600))
}
var minute: Int {
Int((self/60).truncatingRemainder(dividingBy: 60))
}
var second: Int {
Int(truncatingRemainder(dividingBy: 60))
}
var millisecond: Int {
Int((self*1000).truncatingRemainder(dividingBy: 1000))
}
}


extension Int {
var msToSeconds: Double { Double(self) / 1000 }
}


let seconds = 131.531   // 131.531
let time = seconds.minuteSecondMS // "2:11.531"
let millisecond = seconds.millisecond // 531

let ms = 1111
let sec = ms.msToSeconds.minuteSecondMS // "0:01.111"


Date().description(with: .current)        // "Wednesday, October 21, 2020 at 5:44:51 PM Brasilia Standard Time"
let startOfDay = Calendar.current.startOfDay(for: Date())
let secondsFromStartOfDay = Date().timeIntervalSinceReferenceDate - startOfDay.timeIntervalSinceReferenceDate
secondsFromStartOfDay.hourMinuteSecondMS // "17:44:51.705"

Swift - Integer conversion to Hours/Minutes/Seconds

Define

func secondsToHoursMinutesSeconds(_ seconds: Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}

Use

> secondsToHoursMinutesSeconds(27005)
(7,30,5)

or

let (h,m,s) = secondsToHoursMinutesSeconds(27005)

The above function makes use of Swift tuples to return three values at once. You destructure the tuple using the let (var, ...) syntax or can access individual tuple members, if need be.

If you actually need to print it out with the words Hours etc then use something like this:

func printSecondsToHoursMinutesSeconds(_ seconds: Int) {
let (h, m, s) = secondsToHoursMinutesSeconds(seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}

Note that the above implementation of secondsToHoursMinutesSeconds() works for Int arguments. If you want a Double version you'll need to decide what the return values are - could be (Int, Int, Double) or could be (Double, Double, Double). You could try something like:

func secondsToHoursMinutesSeconds(seconds: Double) -> (Double, Double, Double) {
let (hr, minf) = modf(seconds / 3600)
let (min, secf) = modf(60 * minf)
return (hr, min, 60 * secf)
}

NSTimeInterval to HH:mm:ss?

No need to use NSDateFormatter or anything else than division and modulo. NSTimeInterval is just a double containing seconds.

Swift

func stringFromTimeInterval(interval: NSTimeInterval) -> String {
let interval = Int(interval)
let seconds = interval % 60
let minutes = (interval / 60) % 60
let hours = (interval / 3600)
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}

Objective-C

- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
NSInteger ti = (NSInteger)interval;
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
NSInteger hours = (ti / 3600);
return [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds];
}

Convert NSTimeInterval to hours in decimals

Your timediff variable is already a decimal value for the number of seconds. To convert that into hours, divide by 3600.

let timediff = timeDownValue?.timeIntervalSinceDate(timeUpValue!)
var totalTime = timediff / 3600.0

Here, totalTime will be in hours.

How to create a formatter for TimeInterval to print minutes, seconds and milliseconds

I think the way to look at this is that it's a misuse of a date components formatter. This isn't a date of any kind. It's a string consisting of a certain number of minutes, seconds, and milliseconds. Unlike date math, that's a calculation you can perform, and then you are free to present the string however you like.

If you want to use a formatter to help you with user locales and so forth, then you are looking for a measurement formatter (for each of the substrings).

Example (using the new Swift 5.5 formatter notation):

let t1 = Measurement<UnitDuration>(value: 2, unit: .minutes)
let t2 = Measurement<UnitDuration>(value: 4, unit: .seconds)
let t3 = Measurement<UnitDuration>(value: 345, unit: .milliseconds)
let s1 = t1.formatted(.measurement(width: .narrow))
let s2 = t2.formatted(.measurement(width: .narrow))
let s3 = t3.formatted(.measurement(width: .narrow))
let result = "\(s1) \(s2) \(s3)" // "2m 4s 345ms"

Addendum: You say in a comment that you're having trouble deriving the number milliseconds. Here's a possible way. Start with seconds and let the Measurement do the conversion. Then format the resulting value in the formatter. Like this:

let t3 = Measurement<UnitDuration>(value: 0.344657, unit: .seconds)
.converted(to: .milliseconds)
// getting the `0.xxx` from `n.xxx` is easy and not shown here
let s3 = t3.formatted(.measurement(
width: .narrow,
numberFormatStyle: .number.precision(.significantDigits(3))))

You might have to play around a little with the number-formatter part of that, but the point is that a measurement formatter lets you dictate the number format and thus get the truncation / rounding behavior you're after.

How to convert an NSTimeInterval (seconds) into minutes

pseudo-code:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)

How to convert DispatchTimeInterval to NSTimeInterval (or Double)?

DispatchTimeInterval is a enum:

public enum DispatchTimeInterval : Equatable {
case seconds(Int)
case milliseconds(Int)
case microseconds(Int)
case nanoseconds(Int)
case never
}

You can initialize DispatchTimeInterval using:

    let tenSeconds: DispatchTimeInterval = .seconds(10)
let tenNanoseconds: DispatchTimeInterval = .nanoseconds(10)

To get values from enum you need to match value with a case values in enum

    if case .seconds(let value) = tenSeconds {
print("DispatchTimeInterval is seconds \(value)")
} else if case .nanoseconds(let value) = tenNanoseconds {
print("DispatchTimeInterval is seconds \(value)")
}

Converting function might be look following:

func toDouble(_ interval: DispatchTimeInterval) -> Double? {
var result: Double? = 0

switch interval {
case .seconds(let value):
result = Double(value)
case .milliseconds(let value):
result = Double(value)*0.001
case .microseconds(let value):
result = Double(value)*0.000001
case .nanoseconds(let value):
result = Double(value)*0.000000001

case .never:
result = nil
}

return result
}

More about Enumeration see in Apple Documentation

UPDATE:

Create extension to DispatchTimeInterval

extension DispatchTimeInterval {
func toDouble() -> Double? {
var result: Double? = 0

switch self {
case .seconds(let value):
result = Double(value)
case .milliseconds(let value):
result = Double(value)*0.001
case .microseconds(let value):
result = Double(value)*0.000001
case .nanoseconds(let value):
result = Double(value)*0.000000001

case .never:
result = nil
}

return result
}
}


Related Topics



Leave a reply



Submit