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

如何配置NumberFormatter实现整数不显示小数部分的货币格式化

解决NumberFormatter的欧元格式化需求

刚好之前处理过类似的货币格式化需求,你要的效果是整数不显示小数部分,非整数强制显示两位小数,现有代码的问题在于默认的currency样式会强制保留两位小数(哪怕是整数),哪怕设置了alwaysShowsDecimalSeparator = false也没用,因为minimumFractionDigits默认是2,所以整数还是会显示.00。

这里给你两种实现方式,都能完美满足需求:

方式一:封装成扩展(推荐,复用性高)

通过给NumberFormatter写扩展,把判断逻辑和格式化逻辑封装在一起,方便后续调用:

extension NumberFormatter {
    // 创建基础的欧元格式化器
    static func euroFormatter() -> NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencySymbol = "€"
        // 设置locale确保小数分隔符的一致性,如果你需要适配其他地区可以调整这个值
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    }
    
    // 自定义格式化方法,根据数字类型调整小数位数
    func formattedEuroString(from number: NSNumber) -> String? {
        // 判断数字是否为整数:取余1等于0就是整数
        let isWholeNumber = number.doubleValue.truncatingRemainder(dividingBy: 1) == 0
        
        if isWholeNumber {
            // 整数:不显示小数位
            self.minimumFractionDigits = 0
            self.maximumFractionDigits = 0
        } else {
            // 非整数:强制显示两位小数
            self.minimumFractionDigits = 2
            self.maximumFractionDigits = 2
        }
        
        return self.string(from: number)
    }
}

// 调用示例
let formatter = NumberFormatter.euroFormatter()

// 整数测试
if let zeroStr = formatter.formattedEuroString(from: 0) {
    print(zeroStr) // 输出:0 €
}
if let wholeNumStr = formatter.formattedEuroString(from: 123.0) {
    print(wholeNumStr) // 输出:123 €
}

// 非整数测试
if let decimalStr1 = formatter.formattedEuroString(from: 123.9) {
    print(decimalStr1) // 输出:123.90 €
}
if let decimalStr2 = formatter.formattedEuroString(from: 12.1) {
    print(decimalStr2) // 输出:12.10 €
}

方式二:直接写工具函数(快速实现)

如果不需要复用,直接写个简单的工具函数也能搞定:

let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencySymbol = "€"
formatter.locale = Locale(identifier: "en_US_POSIX")

func formatEuroCurrency(number: Double) -> String? {
    let num = NSNumber(value: number)
    let isWholeNumber = num.doubleValue.truncatingRemainder(dividingBy: 1) == 0
    
    // 动态调整小数位数
    formatter.minimumFractionDigits = isWholeNumber ? 0 : 2
    formatter.maximumFractionDigits = isWholeNumber ? 0 : 2
    
    return formatter.string(from: num)
}

// 测试
print(formatEuroCurrency(number: 0.00)!) // 0 €
print(formatEuroCurrency(number: 123.90)!) // 123.90 €
print(formatEuroCurrency(number: 12.1)!) // 12.10 €

关键逻辑说明

核心就是动态修改minimumFractionDigits和maximumFractionDigits:

  • 当数字是整数时,把两个属性都设为0,这样就不会显示小数部分和分隔符
  • 当数字是非整数时,把两个属性都设为2,强制保留两位小数,哪怕原来只有一位(比如12.1会变成12.10)

另外设置locale是为了避免不同地区的小数分隔符差异(比如欧洲部分地区用逗号作为分隔符),如果你的APP需要适配多语言,可以根据用户的系统locale来调整,而不是硬编码en_US_POSIX。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:57:14