How to parse string value like 12:02:21.3213
to NSTimeInterval
? NSDateComponentsFormatter
, available since iOS8, supports only formatting, not parsing.
Asked
Active
Viewed 1.0k times
13

Bartosz Hernas
- 1,130
- 1
- 9
- 17
-
2Possible duplicate of [How can I convert string date to NSDate?](http://stackoverflow.com/questions/24777496/how-can-i-convert-string-date-to-nsdate) – rghome Feb 15 '16 at 11:35
-
@rghome: No, not a duplicate, at least not of *that* question. – "12:02:21.3213" here is a *duration* (which can be represented as a NSTimeInterval), not as a point in time (which would be an NSDate). – Martin R Feb 15 '16 at 11:52
-
Maybe not an exact duplicate. You can parse the time for 1st January 1970 and then get the interval for that date. I guess that is just about a separate answer in itself. – rghome Feb 15 '16 at 11:55
-
I wouldn't be posting both question and an answer if I would find a solution that satisfies me. I was using an appending time to 1st Jan 1970 but it all crapped itself when there were milliseconds. Additionally, I do not know how it would behave when duration would be more than 24h – Bartosz Hernas Feb 15 '16 at 12:31
-
2I tried out NSDateFormatter. It accepts milliseconds, but not microseconds. It doesn't work for hours > 23, so it would appear that NSDateFormatter is not ideal, and you have, indeed, a good question. – rghome Feb 15 '16 at 20:05
3 Answers
14
Here is how you can do it in Swift,
It works for values like
2:12:12
,
02:01:23.123213
Swift 5 (by @Youstanzr):
extension String {
func convertToTimeInterval() -> TimeInterval {
guard self != "" else {
return 0
}
var interval:Double = 0
let parts = self.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
}
Swift 3 (by @Torre Lasley)
func parseDuration(_ timeString:String) -> TimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
Swift 2
func parseDuration(timeString:String) -> NSTimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.componentsSeparatedByString(":")
for (index, part) in parts.reverse().enumerate() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}

Bartosz Hernas
- 1,130
- 1
- 9
- 17
10
The solution provided by Bartosz Hernas worked for me, thank you!
For convenience, here it is for Swift 3:
func parseDuration(_ timeString:String) -> TimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}

Torre Lasley
- 7,243
- 3
- 24
- 12
6
Here is the Swift 5 version that I've made of @Bartosz answer
extension String {
func convertToTimeInterval() -> TimeInterval {
guard self != "" else {
return 0
}
var interval:Double = 0
let parts = self.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
}

Youstanzr
- 605
- 1
- 8
- 16