How to parse an ISO-8601 duration in Objective C?

前端 未结 12 665
清歌不尽
清歌不尽 2020-12-01 06:52

I\'m looking for an easy way to parse a string that contains an ISO-8601 duration in Objective C. The result should be something usable like a NSTimeI

12条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-01 07:39

    Now in Swift! (Yes it's a little long, but it handles all cases and singular/plural).

    Handles Years, Months, Weeks, Days, Hours, Minutes, and Seconds!

    func convertFromISO8601Duration(isoValue: AnyObject) -> String? {
    
        var displayedString: String?
        var hasHitTimeSection = false
        var isSingular = false
    
        if let isoString = isoValue as? String {
    
            displayedString = String()
    
            for val in isoString {
    
    
                if val == "P" {
                    // Do nothing when parsing the 'P'
                    continue
    
                }else if val == "T" {
                    // Indicate that we are now dealing with the 'time section' of the ISO8601 duration, then carry on.
                    hasHitTimeSection = true
                    continue
                }
    
                var tempString = String()
    
                if val >= "0" && val <= "9" {
    
                    // We need to know whether or not the value is singular ('1') or not ('11', '23').
                    if let safeDisplayedString = displayedString as String!
                        where count(displayedString!) > 0 && val == "1" {
    
                        let lastIndex = count(safeDisplayedString) - 1
    
                        let lastChar = safeDisplayedString[advance(safeDisplayedString.startIndex, lastIndex)]
    
                            //test if the current last char in the displayed string is a space (" "). If it is then we will say it's singular until proven otherwise.
                        if lastChar == " " {
                            isSingular = true
                        } else {
                            isSingular = false
                        }
                    }
                    else if val == "1" {
                        // if we are just dealing with a '1' then we will say it's singular until proven otherwise.
                        isSingular = true
                    }
                    else {
                        // ...otherwise it's a plural duration.
                        isSingular = false
                    }
    
                    tempString += "\(val)"
    
                    displayedString! += tempString
    
                } else {
    
                    // handle the duration type text. Make sure to use Months & Minutes correctly.
                    switch val {
    
                    case "Y", "y":
    
                        if isSingular {
                            tempString += " Year "
                        } else {
                            tempString += " Years "
                        }
    
                        break
    
                    case "M", "m":
    
                        if hasHitTimeSection {
    
                            if isSingular {
                                tempString += " Minute "
                            } else {
                                tempString += " Minutes "
                            }
                        }
                        else {
    
                            if isSingular {
                                tempString += " Month "
                            } else {
                                tempString += " Months "
                            }
                        }
    
                        break
    
                    case "W", "w":
    
                        if isSingular {
                            tempString += " Week "
                        } else {
                            tempString += " Weeks "
                        }
    
                        break
    
                    case "D", "d":
    
                        if isSingular {
                            tempString += " Day "
                        } else {
                            tempString += " Days "
                        }
    
                        break
    
                    case "H", "h":
    
                        if isSingular {
                            tempString += " Hour "
                        } else {
                            tempString += " Hours "
                        }
    
                        break
    
                    case "S", "s":
    
                        if isSingular {
                            tempString += " Second "
                        } else {
                            tempString += " Seconds "
                        }
    
                        break
    
                    default:
                        break
    
                    }
    
                    // reset our singular flag, since we're starting a new duration.
                    isSingular = false
    
                    displayedString! += tempString
    
                }
    
            }
    
        }
    
        return displayedString
    }
    

提交回复
热议问题