假设我们具有以下结构:
struct TestCod: Codable {
var txt = ""
var date = Date()
}
如果我们期望JSON具有两种相似的格式,那么如何处理解码?
JSON A:
{
"txt":"stack",
"date":589331953.61679399
}
JSON B:
{
"txt":"overflow",
"date":"2019-09-05"
}
答案 0 :(得分:2)
如我已经在评论中提到的可能重复的帖子中所示,您需要创建一个自定义日期解码策略:
首先创建用于解析日期字符串的日期格式化程序(请注意,这假定您的日期是本地时间,如果您需要UTC时间或服务器时间,则需要相应地设置格式化程序时区属性):
extension Formatter {
static let yyyyMMdd: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
}
然后创建自定义解码策略,以尝试您可能需要的所有可能的日期解码策略:
extension JSONDecoder.DateDecodingStrategy {
static let deferredORyyyyMMdd = custom {
let container = try $0.singleValueContainer()
do {
return try Date(timeIntervalSinceReferenceDate: container.decode(Double.self))
} catch {
let string = try container.decode(String.self)
if let date = Formatter.yyyyMMdd.date(from: string) {
return date
}
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
}
}
}
游乐场测试:
struct TestCod: Codable {
let txt: String
let date: Date
}
let jsonA = """
{
"txt":"stack",
"date":589331953.61679399
}
"""
let jsonB = """
{
"txt":"overflow",
"date":"2019-09-05"
}
"""
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .deferredORyyyyMMdd
let decodedJSONA = try! decoder.decode(TestCod.self, from: Data(jsonA.utf8))
decodedJSONA.date // "Sep 4, 2019 at 8:19 PM"
let decodedJSONB = try! decoder.decode(TestCod.self, from: Data(jsonB.utf8))
decodedJSONB.date // "Sep 5, 2019 at 12:00 AM"