How to parse a ISO 8601 duration format in Swift?

后端 未结 3 595
夕颜
夕颜 2021-01-24 15:57

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

3条回答
  •  后悔当初
    2021-01-24 16:48

    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

提交回复
热议问题