您可以使用两个不同的日期格式器(带和不带小数秒)并创建自定义的DateDecodingStrategy。如果在解析API返回的日期时失败,则可以按@PauloMattos的建议在注释中引发DecodingError:
iOS 9,macOS 10.9,tvOS 9,watchOS 2,Xpre 9或更高版本
自定义ISO8601DateFormatter:
extension Formatter { static let iso8601withFractionalSeconds: DateFormatter = { let formatter = DateFormatter() formatter.calendar = Calendar(identifier: .iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" return formatter }() static let iso8601: DateFormatter = { let formatter = DateFormatter() formatter.calendar = Calendar(identifier: .iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" return formatter }()}习惯
DateDecodingStrategy:
extension JSONDeprer.DateDecodingStrategy { static let customISO8601 = custom { let container = try $0.singlevalueContainer() let string = try container.depre(String.self) if let date = Formatter.iso8601withFractionalSeconds.date(from: string) ?? Formatter.iso8601.date(from: string) { return date } throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: (string)") }}习惯
DateEncodingStrategy:
extension JSONEnprer.DateEncodingStrategy { static let customISO8601 = custom { var container = $1.singlevalueContainer() try container.enpre(Formatter.iso8601withFractionalSeconds.string(from: $0)) }}编辑/更新 :
Xpre 10•Swift 4.2或更高版本•iOS 11.2.1或更高版本
ISO8601DateFormatter现在支持
formatOptions
.withFractionalSeconds:
extension Formatter { static let iso8601withFractionalSeconds: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] return formatter }() static let iso8601: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withInternetDateTime] return formatter }()}习惯
DateDecodingStrategy和
DateEncodingStrategy将与上面显示的相同。
// Playground testingstruct ISODates: Codable { let dateWith9FS: Date let dateWith3FS: Date let dateWith2FS: Date let dateWithoutFS: Date}let isoDatesJSON = """{"dateWith9FS": "2017-06-19T18:43:19.532123456Z","dateWith3FS": "2017-06-19T18:43:19.532Z","dateWith2FS": "2017-06-19T18:43:19.53Z","dateWithoutFS": "2017-06-19T18:43:19Z",}"""let isoDatesData = Data(isoDatesJSON.utf8)let deprer = JSonDeprer()deprer.dateDecodingStrategy = .customISO8601do { let isoDates = try deprer.depre(ISODates.self, from: isoDatesData) print(Formatter.iso8601withFractionalSeconds.string(from: isoDates.dateWith9FS)) // 2017-06-19T18:43:19.532Z print(Formatter.iso8601withFractionalSeconds.string(from: isoDates.dateWith3FS)) // 2017-06-19T18:43:19.532Z print(Formatter.iso8601withFractionalSeconds.string(from: isoDates.dateWith2FS)) // 2017-06-19T18:43:19.530Z print(Formatter.iso8601withFractionalSeconds.string(from: isoDates.dateWithoutFS)) // 2017-06-19T18:43:19.000Z} catch { print(error)}


