所以,我的json中有iso8601日期,看起来像“ 2016-06-07T17:20:00.000 + 02:00”
有没有办法使用swift4解析这些iso8601日期?我缺少明显的东西吗?
我尝试了以下操作,但是仅jsonShipA中的dateString“ 2016-06-07T17:20:00Z”是可解析的…。
import Foundation struct Spaceship : Codable { var name: String var createdAt: Date } let jsonShipA = """ { "name": "Skyhopper", "createdAt": "2016-06-07T17:20:00Z" } """ let jsonShipB = """ { "name": "Skyhopper", "createdAt": "2016-06-07T17:20:00.000+02:00" } """ let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 let dataA = jsonShipA.data(using: .utf8)! if let decodedShip = try? decoder.decode(Spaceship.self, from: dataA) { print("jsonShipA date = \(decodedShip.createdAt)") } else { print("Failed to decode iso8601 date format from jsonShipA") } let dataB = jsonShipB.data(using: .utf8)! if let decodedShip = try? decoder.decode(Spaceship.self, from: dataB) { print("jsonShipA date = \(decodedShip.createdAt)") } else { print("Failed to decode iso8601 date format from jsonShipB") }
游乐场的输出为:
jsonShipA date = 2016-06-07 17:20:00 +0000 Failed to decode iso8601 date format from jsonShipB
引发的错误是“预期日期字符串为ISO8601格式”。但是据我所知,日期“ 2016-06-07T17:20:00.000 + 02:00”是有效的ISO8601日期
您可以这样使用:
enum DateError: String, Error { case invalidDate } let decoder = JSONDecoder() let formatter = DateFormatter() formatter.calendar = Calendar(identifier: .iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(secondsFromGMT: 0) decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in let container = try decoder.singleValueContainer() let dateStr = try container.decode(String.self) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" if let date = formatter.date(from: dateStr) { return date } formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" if let date = formatter.date(from: dateStr) { return date } throw DateError.invalidDate })