You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Swift Duration创建仅显示秒数的自定义TimeFormatStyle

自定义Swift Duration的TimeFormatStyle处理秒级时长

Swift的Duration提供的.hourMinute、.hourMinuteSecond等预定义格式,没法覆盖仅含秒数或超过一天的时长场景。要实现自定义格式,将不足一分钟的时长(如9秒541毫秒)格式化为9.54(或补零的09.54),且支持毫秒四舍五入,可按以下方式实现:

实现自定义FormatStyle

通过自定义结构体遵循FormatStyle协议,控制时长的格式化逻辑:

struct SecondsDecimalFormatStyle: FormatStyle {
    typealias FormatInput = Duration
    typealias FormatOutput = String
    
    // 控制秒数整数部分的最小位数,设为2时会补零(如09.54)
    var minimumIntegerDigits: Int = 1
    
    func format(_ value: Duration) -> String {
        // 将Duration转换为总秒数(保留小数精度)
        let totalNanoseconds = value.components.nanoseconds
        let totalSeconds = Double(totalNanoseconds) / 1_000_000_000
        
        // 四舍五入到两位小数,避免截断毫秒
        let roundedSeconds = (totalSeconds * 100).rounded() / 100
        
        // 拆分整数和小数部分,格式化输出
        let integerPart = Int(roundedSeconds)
        let fractionalPart = Int((roundedSeconds.truncatingRemainder(dividingBy: 1)) * 100)
        let formatPattern = "%0\(minimumIntegerDigits)d.%02d"
        
        return String(format: formatPattern, integerPart, fractionalPart)
    }
}

// 给Duration扩展便捷调用方法
extension Duration {
    func formatted(with style: SecondsDecimalFormatStyle) -> String {
        style.format(self)
    }
}

使用示例

// 9秒541毫秒 → 四舍五入为9.54
let shortDuration1 = Duration.seconds(9) + Duration.milliseconds(541)
print(shortDuration1.formatted(with: SecondsDecimalFormatStyle())) // 输出: 9.54
print(shortDuration1.formatted(with: SecondsDecimalFormatStyle(minimumIntegerDigits: 2))) // 输出: 09.54

// 9秒547毫秒 → 四舍五入为9.55
let shortDuration2 = Duration.seconds(9) + Duration.milliseconds(547)
print(shortDuration2.formatted(with: SecondsDecimalFormatStyle())) // 输出: 9.55

// 超过一分钟的时长也能处理:2分30秒547毫秒 → 150.55
let longDuration = Duration.minutes(2) + Duration.seconds(30.547)
print(longDuration.formatted(with: SecondsDecimalFormatStyle())) // 输出: 150.55

关键逻辑说明

  • 精度处理:通过纳秒数转换为秒的Double值,保证计算精度,避免整数除法丢失小数部分。
  • 四舍五入:通过(totalSeconds * 100).rounded() / 100实现两位小数的四舍五入,替代默认的截断行为。
  • 补零控制:通过minimumIntegerDigits参数灵活控制秒数整数部分的显示位数,满足不同场景的格式需求。

内容的提问来源于stack exchange,提问作者Brian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:02:16