2017-12-30 18 views
1

私は文字列の書式設定に使用する以下の関数を持っています。文字列はこの "PT1H3M20S"のようなもので、1時間3分20秒という意味です。私の関数では、文字列を1:03:20にフォーマットしたいが、うまくいきますが、時には、この "PT1H20S"のような文字列が1時間20秒、関数形式は1:20人々に1分20秒としてそれを読ませる。助言がありますか?文字列の形式の問題 - スウィフト

func formatDuration(videoDuration: String) -> String{ 
    let formattedDuration = videoDuration.replacingOccurrences(of: "PT", with: "").replacingOccurrences(of: "H", with:":").replacingOccurrences(of: "M", with: ":").replacingOccurrences(of: "S", with: "") 
    let components = formattedDuration.components(separatedBy: ":") 
    var duration = "" 
    for component in components { 
     duration = duration.count > 0 ? duration + ":" : duration 
     if component.count < 2 { 
      duration += "0" + component 
      continue 
     } 
     duration += component 
    } 
    // instead of 01:10:10, display 1:10:10 
    if duration.first == "0"{ 
     duration.remove(at: duration.startIndex) 
    } 
    return duration 
} 

はそれを呼び出します。

print(formatDuration(videoDuration: "PT1H15S") 
+0

正規表現を使用しますか? – Paulw11

答えて

0

あなたはまた、自分の時間、分、秒のインデックスを検索し、ビデオ再生時間をフォーマットするDateComponentsFormatter位置スタイルを使用することができます。

は、静的な位置日付コンポーネントフォーマッタを作成します。

extension Formatter { 
    static let positional: DateComponentsFormatter = { 
     let formatter = DateComponentsFormatter() 
     formatter.unitsStyle = .positional 
     return formatter 
    }() 
} 

そして、あなたをフォーマット時間方法:

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" 
2

あなたは、各番号の後にあるものを単位確認する必要があるので、あなたは文字列からユニットを除去することにより、起動することはできません。

Scannerを使用して元の文字列を解析し、最終結果を作成する時間、分、秒数を検出するソリューションです。

これは、渡された文字列が無効であることを示すために、戻り値をオプションに変更します。

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") 

出力:あなたのケースでは

午前1時03分20秒
1時00分15秒
悪い

+0

ニース!文字列が "30M20S"の場合、出力は0:31:33です。 31:33のみとして出力を表示する方法はありますか?ありがとう! –

+0

更新された回答を参照してください。 – rmaddy

1

、あなたの文字列は数分のための文字を運ばないので、あなた文字列に分が含まれていないかどうかを確認し、1:20の間に "00:"を追加して適切に書式を設定します。