如何为TimeInterval创建格式化器以输出分钟、秒及毫秒
实现方案
首先明确:DateComponentsFormatter 原生不支持直接将秒的小数部分输出为独立的毫秒单位,也不支持直接自定义秒后的小数位数。你之前的尝试不生效是因为 allowsFractionalUnits 仅会将小数部分合并到秒的数值中,不会拆分为独立的毫秒/纳秒单位显示,添加.nanosecond到allowedUnits也不会触发毫秒单位的输出。
方案1:自定义拆分实现独立毫秒单位输出(适配自定义小数位数)
如果你需要严格输出 2m 4s 345ms 这种拆分单位的格式,可以手动拆分TimeInterval的各部分数值,自行拼接单位:
extension TimeInterval { func formatToMinSecMs(fractionDigits: Int = 3) -> String { let totalSeconds = self let minutes = Int(totalSeconds) / 60 let seconds = Int(totalSeconds) % 60 // 按要求的小数位数计算小数部分 let multiplier = pow(10, Double(fractionDigits)) let fractionalPart = (totalSeconds - Double(Int(totalSeconds))) * multiplier let ms = Int(fractionalPart.rounded()) var components: [String] = [] if minutes > 0 { components.append("\(minutes)m") } components.append("\(seconds)s") components.append("\(ms)ms") return components.joined(separator: " ") } } // 使用示例 let t: TimeInterval = 124.344657 print(t.formatToMinSecMs()) // 输出:2m 4s 345ms // 自定义保留1位小数精度 print(t.formatToMinSecMs(fractionDigits: 1)) // 输出:2m 4s 3ms
方案2:配合NumberFormatter实现带小数的秒显示
如果你可以接受秒数带小数的格式(如 2m 4.345s),可以结合DateComponentsFormatter和NumberFormatter实现:
let t: TimeInterval = 124.344657 let formatter = DateComponentsFormatter() formatter.unitsStyle = .abbreviated formatter.allowedUnits = [.minute] formatter.zeroFormattingBehavior = .dropAll let minutePart = formatter.string(from: t) ?? "" let secondsPart = t.truncatingRemainder(dividingBy: 60) let numberFormatter = NumberFormatter() numberFormatter.minimumFractionDigits = 3 numberFormatter.maximumFractionDigits = 3 numberFormatter.decimalSeparator = "." let secondStr = numberFormatter.string(from: NSNumber(value: secondsPart)) ?? "" let result = [minutePart, "\(secondStr)s"].filter { !$0.isEmpty }.joined(separator: " ") // 输出:2m 4.345s
内容的提问来源于stack exchange,提问作者New Dev
相关产品推荐
相关产品推荐

