I have a function below which I use to format a string. The string is something like this \"PT1H3M20S\" which means 1 hour 3 minutes and 20 seconds. In my function, I want to fo
In your case, your string carries no character for minutes, so you can make a check if the string does not contain minutes, then add "00:" between 1:20 and format appropriately.
Since you need to see what unit is after each number, you can't start by removing the units from the string.
Here is a solution that uses Scanner
to parse the original string and finds the number of hours, minutes, and seconds to build the final result.
This also changes the return value to be optional to indicate that the passed in string isn't valid.
func formatDuration(videoDuration: String) -> String? {
let scanner = Scanner(string: videoDuration)
if scanner.scanString("PT", into: nil) {
var hours = 0
var mins = 0
var secs = 0
let units = CharacterSet(charactersIn: "HMS")
while !scanner.isAtEnd {
var num = 0
if scanner.scanInt(&num) {
var unit: NSString?
if scanner.scanCharacters(from: units, into: &unit) {
switch unit! {
case "H":
hours = num
case "M":
mins = num
case "S":
secs = num
default:
return nil // Invalid unit
}
} else {
return nil // No unit after the number
}
} else {
return nil // No integer
}
}
if hours > 0 {
return String(format: "%d:%02d:%02d", hours, mins, secs)
} else {
return String(format: "%02d:%02d", mins, secs)
}
} else {
return nil // No leading PT
}
}
print(formatDuration(videoDuration: "PT1H3M20S") ?? "bad")
print(formatDuration(videoDuration: "PT1H15S") ?? "bad")
print(formatDuration(videoDuration: "PT4M6") ?? "bad")
Output:
1:03:20
1:00:15
bad
You can also just search the indexes of your hours, minutes and seconds and use DateComponentsFormatter positional style to format your video duration:
Create a static positional date components formatter:
extension Formatter {
static let positional: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional
return formatter
}()
}
And your format duration method:
func formatVideo(duration: String) -> String {
var duration = duration
if duration.hasPrefix("PT") { duration.removeFirst(2) }
let hour, minute, second: Double
if let index = duration.index(of: "H") {
hour = Double(duration[..<index]) ?? 0
duration.removeSubrange(...index)
} else { hour = 0 }
if let index = duration.index(of: "M") {
minute = Double(duration[..<index]) ?? 0
duration.removeSubrange(...index)
} else { minute = 0 }
if let index = duration.index(of: "S") {
second = Double(duration[..<index]) ?? 0
} else { second = 0 }
return Formatter.positional.string(from: hour * 3600 + minute * 60 + second) ?? "0:00"
}
let duration = "PT1H3M20S"
formatVideo(duration: duration) // "1:03:20"