首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在同一结构中对多种日期格式进行JSON编码

如何在同一结构中对多种日期格式进行JSON编码
EN

Stack Overflow用户
提问于 2019-01-30 06:16:29
回答 1查看 404关注 0票数 1

需要编码到JSON,一个有2个日期实例变量(日期和时间)的结构,但是,我需要用不同的格式编码每个日期实例变量,即。"day":"yyyy-M-d“和"time":"H:m:s”。

我写了一个自定义解码器,工作没有问题。但不确定如何编写所需的自定义编码器来解决此问题。

例如,我可以解码如下JSON字符串:{ "biometrics“:{"biometricId":1,"amount":2.1,"source":"Alderaan","day":"2019-1-3","time":"11-3-3","unitId":2},{"biometricId":10,"amount":3.1,"source":"Endoor","day":"2019-2-4","time":"11-4-4","unitId":20} }

然而,当我对其进行编码时,我只能将其编码为单一的日期格式:(帮助,不胜感激。谢谢。

代码语言:javascript
复制
import UIKit

let biometricsJson = """
{ "biometrics" : [
    {"biometricId":1,"amount":2.1,"source":"Alderaan","day":"2019-1-3","time":"11-3-3","unitId":2},
    {"biometricId":10,"amount":3.1,"source":"Endoor","day":"2019-2-4","time":"11-4-4","unitId":20}]
}
"""

struct Biometrics: Codable {
    var biometrics: [Biometric]
}

struct Biometric: Codable {

    var biometricId: Int
    var unitId: Int
    var source: String?
    var amount: Double
    var day: Date
    var time: Date

    init(biometricId: Int, unitId: Int, source: String, amount: Double, day: Date, time: Date){
        self.biometricId = biometricId
        self.unitId = unitId
        self.source = source
        self.amount = amount
        self.day = day
        self.time = time
    }
}

extension Biometric {

    static let decoder: JSONDecoder = {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .custom { decoder in
            let container = try decoder.singleValueContainer()
            let dateString = try container.decode(String.self)

            let formatter = DateFormatter()
            formatter.timeZone = TimeZone.current
            formatter.dateFormat = "H:m:s"
            if let date = formatter.date(from: dateString) {
                return date
            }

            formatter.dateFormat = "yyyy-M-d"
            if let date = formatter.date(from: dateString) {
                return date
            }
            throw DecodingError.dataCorruptedError(in: container,
                                                   debugDescription: "Cannot decode date string \(dateString)")
        }
        return decoder
    }()
}

let biometrics = try Biometric.decoder.decode(Biometrics.self, from:biometricsJson.data(using: .utf8)!)

let jsonEncoder = JSONEncoder()
let encodedJson = try jsonEncoder.encode(biometrics)
let jsonString = String(data: encodedJson, encoding: .utf8)
if biometricsJson != jsonString {
    print("error: decoding, then encoding does not give the same string")
    print("biometricsJson: \(biometricsJson)")
    print("jsonString: \(jsonString!)")
}

我希望经过编码的JSON能够被解码器解码。即biometricsJson == jsonString

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-30 07:04:11

在自定义encode(to:)中,只需使用所需的格式化程序将每个值编码为一个字符串。JSON中没有"date“类型;它只是一个字符串。大致是这样的:

代码语言:javascript
复制
enum CodingKeys: CodingKey {
    case biometricId, amount, source, day, time, unitId
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(biometricId, forKey: .biometricId)
    try container.encode(unitId, forKey: .unitId)
    try container.encode(source, forKey: .source)
    try container.encode(amount, forKey: .amount)

    let formatter = DateFormatter()
    formatter.timeZone = TimeZone.current
    formatter.dateFormat = "H:m:s"
    let timeString = formatter.string(from: time)
    try container.encode(timeString, forKey: .time)

    formatter.dateFormat = "yyyy-M-d"
    let dayString = formatter.string(from: day)
    try container.encode(dayString, forKey: .day)
}

但请注意,您不能测试等价的字符串。JSON字典不能保持顺序,因此无法保证逐个字符匹配。

注意,如果你真的想要有日期和时间,你应该考虑DateComponents而不是Date。日期是时间上的特定实例;它不在任何时区,它不能只是小时、分钟和秒。

此外,您使用双精度将导致舍入差异。因此,2.1将被编码为2.1000000000000001。如果这是一个问题,您应该为amount使用Decimal,而不是Double

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54430461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档