xxxxxx.yyyyyy
, "xxxxxx.yyyyyy"
, xxxxxx
どの形式でも受け取れるようにします。
Double等でパースすると精度が足りないのでDecimalを使用します。
import Foundation @main public struct hello_swift { public static func main() { let decoder = JSONDecoder() let encoder = JSONEncoder() let json = "{\"a\": 1675912938, \"b\": 1675912938.1675912938, \"c\": \"1675912938.1675912938\"}" let decoded = try! decoder.decode(Dictionary<String, Instant>.self, from: Data(json.utf8)) print(decoded) print(String(decoding: try! encoder.encode(decoded), as: UTF8.self)) } } final public class Instant: Codable, LosslessStringConvertible { public let seconds: Int64 public let nano: Int64 public init(_ seconds: Int64, _ nano: Int64) { self.seconds = seconds self.nano = nano } public convenience init?(_ description: String) { try? self.init(decinal: NSDecimalNumber(string: description)) } private init(decinal: NSDecimalNumber) throws { let splitedText = decinal.stringValue.split(separator: ".") self.seconds = Int64(splitedText[0]) ?? 0 if splitedText.count >= 2 { self.nano = Int64(splitedText[1]) ?? 0 } else { self.nano = 0 } } public convenience init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if let decimal = try? container.decode(Decimal.self) { try self.init(decinal: NSDecimalNumber(decimal: decimal)) } else if let text = try? container.decode(String.self) { try self.init(decinal: NSDecimalNumber(string: text)) } else { throw NSError(domain: "parse failed. \(decoder)", code: -1, userInfo: nil) } } public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(Decimal(string: "\(seconds).\(nano)")) } public var description: String { return "\(seconds).\(nano)" } }
["c": 1675912938.1675912938, "b": 1675912938.1675912938, "a": 1675912938.0] {"a":1675912938,"b":1675912938.1675912938,"c":1675912938.1675912938}