- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
NumberFormatter
使得在屏幕上显示值时格式化货币非常容易:
let decimal = Decimal(25.99)
let decimalNumberFormatter = NumberFormatter()
decimalNumberFormatter.numberStyle = .currencyAccounting
let output = decimalNumberFormatter.string(for: decimal)
// output = "$25.99"
以上代码适用于任何 Decimal
或 Double
值。小数位数始终与所使用的区域设置相匹配。
将浮点货币值序列化为 JSON 并不是那么简单。
具有以下序列化方法(注意强制解包):
func serialize(prices: Any...) {
let data = try! JSONSerialization.data(withJSONObject: ["value": prices], options: [])
let string = String(data: data, encoding: .utf8)!
print(string)
}
然后我们可以用不同的值和类型调用它。 Double
、Decimal
和 NSDecimalNumber
(应该从 Swift 的 Decimal
桥接而来)无法正确呈现某些值例。
serialize(prices: 125.99, 16.42, 88.56, 88.57, 0.1 + 0.2)
// {"value":[125.99,16.42,88.56,88.56999999999999,0.3]}
serialize(prices: Decimal(125.99), Decimal(16.42), Decimal(88.56), Decimal(88.57), Decimal(0.1) + Decimal(0.2))
// {"value":[125.98999999999997952,16.420000000000004096,88.56,88.57,0.3]}
serialize(prices: NSDecimalNumber(value: 125.99), NSDecimalNumber(value: 16.42), NSDecimalNumber(value: 88.56), NSDecimalNumber(value: 88.57), NSDecimalNumber(value: 0.1).adding(NSDecimalNumber(value: 0.2)))
// {"value":[125.98999999999997952,16.420000000000004096,88.56,88.57,0.3]}
我不打算将数字序列化为货币(不需要货币符号,整数 (5
) 或单个小数位 (0.3
) 都可以)。但是,我正在寻找一种解决方案,其中序列化输出包含的小数位数不超过给定货币允许的小数位数(区域设置)。
也就是说,在将浮点值序列化为 JSON 时,有什么方法可以限制或指定要使用的小数位数吗?
更新#1:使用更多数据类型进行测试,令人惊讶的是,Float
和 Float32
似乎都适用于两位小数的货币。 Float64
失败为 Double
(可能它们是同一类型的别名)。
serialize(prices: Float(125.99), Float(16.42), Float(88.56), Float(88.57), Float(0.1) + Float(0.2))
// {"value":[125.99,16.42,88.56,88.57,0.3]}
serialize(prices: Float32(125.99), Float32(16.42), Float32(88.56), Float32(88.57), Float32(0.1) + Float32(0.2))
// {"value":[125.99,16.42,88.56,88.57,0.3]}
serialize(prices: Float64(125.99), Float64(16.42), Float64(88.56), Float64(88.57), Float64(0.1) + Float64(0.2))
// {"value":[125.99,16.42,88.56,88.56999999999999,0.3]}
不过,很难知道它们是否在所有情况下都能正常工作。 Float80
无法序列化并出现 _NSJSONWriter
异常。
最佳答案
在对此事进行了一些研究之后,一位同事发现使用 NSDecimalNumberHandler
舍入指定行为的值可以解决 JSON 序列化问题。
fileprivate let currencyBehavior = NSDecimalNumberHandler(roundingMode: .bankers, scale: 2, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)
extension Decimal {
var roundedCurrency: Decimal {
return (self as NSDecimalNumber).rounding(accordingToBehavior: currencyBehavior) as Decimal
}
}
按照帖子中的示例代码,我们得到了所需的输出:
serialize(prices: Decimal(125.99).roundedCurrency, Decimal(16.42).roundedCurrency, Decimal(88.56).roundedCurrency, Decimal(88.57).roundedCurrency, (Decimal(0.1) + Decimal(0.2)).roundedCurrency)
// {"value":[125.99,16.42,88.56,88.57,0.3]}
有效!对 10000 个值(从 0.0 到 99.99)进行了测试,没有发现任何问题。
如果需要,可以将比例调整为当前语言环境的小数位数:
var currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currencyAccounting
let scale = currencyFormatter.maximumFractionDigits
// scale == 2
关于json - 使用 JSONSerialization 序列化货币时指定小数位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45420375/
问题 我有一个 Spring MVC 应用程序,它要求我将某个实体列表的 id 和名称转换为具有特定格式的 JSON 对象数组,并在某个请求上输出。也就是说,我需要一个像这样的 JSON 对象数组:
当我阅读最新 RestSharp 的 readme.txt 时: *** IMPORTANT CHANGE IN RESTSHARP VERSION 103 *** In 103.0, JSON.NE
我有两个类(class)。以二等领域第一。 class A { @JsonSerializer(using = CustomBSerializer.class) private B b; }
有什么方法可以从 JsonSerializer 类中取出设置并在新的 JsonSerializer 中重新实现它们? 似乎没有任何方法可以做那样的事情。我发现最好的是通过反射调用的私有(private
在我的java应用程序中,我分别使用 JsonSerializer 和 JsonSerializer() 来序列化 java.util.Date 和 java.sql.Timestamp 字段。但问题
我想使用 Foundation 的 JSONSerialization.data(withJSONObject obj: AnyObject, options opt:writingOptions =
根据PHP手册 If a Pure Enum is serialized to JSON, an error will be thrown. If a Backed Enum is serialize
我有一个父类,我在其上指定了一个像这样的自定义反序列化器 - @JsonDeserialize(using = CustomDeserializer.class) public class Paren
根据PHP手册 If a Pure Enum is serialized to JSON, an error will be thrown. If a Backed Enum is serialize
我有一个位于 .jar 中的类,但无法修改。 它在类上有一个 @JsonSerialize() 注释。 @JsonSerialize(using = SomeClassSerializer.class
我正在使用 JSON token 开发 iOS,但遇到了 unsupported_grant_type 错误。我正在开发的代码如下 let params = ["grant_type": "passw
我有以下代码将 joda 的 LocalDate 序列化为字符串: public class JodaDateSerializer extends JsonSerializer { priva
我想添加一个包装器,其命名是在运行时确定的,因为它取决于类名(我可以使用@JsonRootName,但我不想这样做,因为我必须在每个子类上使用它,即效率不高)。 我想我应该使用 @JsonSerial
我编写了一个自定义的 JsonSerializer 来将 BigDecimal 转换为 String。我想使用 @JsonSerialize 注释调用此序列化程序,但有条件地,即如果特定 boolea
JSONSerialization 未在服务器发送时序列化数据。它反转数据。我使用后端的数据过滤 API。它发送准确的数据,我还检查了 postman 和 Android 端,但 iOS 代码更改了响
我正在尝试将 SwiftyJSON 与我的 JSON api 数据一起使用,但我无法理解转换的工作原理。 这是 SwiftyJSON Git 的链接:https://github.com/Swifty
我有一个自定义类 public class Balance: NSObject { var details: String var date: Date var amount:
我在解析 json 时遇到错误 "hoursOfOperation" : { "sat" : { "enabled" : true, "schedule"
什么是 option: [] in JSONSerialization in swift let jsonData = try JSONSerialization.data(withJSONObjec
我在将我的模型翻译成字典时遇到了问题。我的模型继承自 Codable,当使用 JSONSerialization 时,我得到了一个字典,其形式为: (...,"sensors": ( { accx =
我是一名优秀的程序员,十分优秀!