8

I need to subtract a DispatchTimeInterval from an NSTimeInterval (or Double).

Is there a standard way to convert a DispatchTimeInterval to an NSTimeInterval?

meaning-matters
  • 19,878
  • 9
  • 76
  • 125
  • DispatchTimeInterval is used with DispatchTime, not with (NS)Date or (NS)TimeInterval. Can you tell more about why you need this? – In any case, DispatchTimeInterval is an enum, and converting it to a Double would be a matter of a simple switch/case. – Martin R Dec 08 '17 at 12:58
  • @MartinR There's a timer which is set with a `DispatchTimeInterval` and I measure elapsed real time in `NSTimeInterval`. I need to subtract both to get a delay. – meaning-matters Dec 08 '17 at 13:50

2 Answers2

16

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
    }
}
Ihar Katkavets
  • 1,287
  • 15
  • 24
9

A swifty solution would be to create a TimeInterval extension and add a failable initializer with a DispatchTimeInterval parameter in it. The following Swift 5 code shows how to implement it:

import Foundation

extension TimeInterval {

    init?(dispatchTimeInterval: DispatchTimeInterval) {
        switch dispatchTimeInterval {
        case .seconds(let value):
            self = Double(value)
        case .milliseconds(let value):
            self = Double(value) / 1_000
        case .microseconds(let value):
            self = Double(value) / 1_000_000
        case .nanoseconds(let value):
            self = Double(value) / 1_000_000_000
        case .never:
            return nil
        }
    }

}

Usage:

let dispatchTimeInterval = DispatchTimeInterval.seconds(5)
let timeInterval = TimeInterval(dispatchTimeInterval: dispatchTimeInterval)
print(String(describing: timeInterval)) // Optional(5.0)
let dispatchTimeInterval = DispatchTimeInterval.milliseconds(30)
let timeInterval = TimeInterval(dispatchTimeInterval: dispatchTimeInterval)
print(String(describing: timeInterval)) // Optional(0.03)
Imanou Petit
  • 84,140
  • 26
  • 249
  • 211