Skip to content

Instantly share code, notes, and snippets.

@eMdOS
Last active August 23, 2019 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eMdOS/cb33f881b1724b160bf41669e98990c1 to your computer and use it in GitHub Desktop.
Save eMdOS/cb33f881b1724b160bf41669e98990c1 to your computer and use it in GitHub Desktop.
Decoding custom date formats using Decodable
extension KeyedDecodingContainer where Key: CodingKey {
func decodeDate(from key: Key, using formats: String...) throws -> Date {
let dateAsString = try decode(String.self, forKey: key)
let dateFormatter = DateFormatter()
for format in formats {
dateFormatter.dateFormat = format
guard let date = dateFormatter.date(from: dateAsString) else {
continue
}
return date
}
let context = DecodingError.Context(codingPath: [], debugDescription: "Cannot decode date: \(dateAsString)")
throw DecodingError.dataCorrupted(context)
}
}
extension String {
static let iso8601format = "yyyy-MM-dd'T'HH:mm:ss'Z'"
static let iso8601fractionalFormat = "yyyy-MM-dd'T'HH:mm:ss.S'Z'"
static let customDate = "MM/dd/yyyy HH:mm:ss"
}

Usage

struct DateWrapper {
    let dateISO8601: Date
    let dateISO8601withFractionalSeconds: Date
    let customDate: Date
}

extension DateWrapper {
    enum CodingKeys: String, CodingKey {
        case dateISO8601, dateISO8601withFractionalSeconds, customDate
    }
}

extension DateWrapper: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        dateISO8601 = try container.decodeDate(from: .dateISO8601, using: .iso8601format)
        dateISO8601withFractionalSeconds = try container.decodeDate(from: .dateISO8601withFractionalSeconds, using: .iso8601fractionalFormat)
        customDate = try container.decodeDate(from: .customDate, using: .customDate)
    }
}
let json: String = """
{
  "dateISO8601": "2019-03-14T12:53:26",
  "dateISO8601withFractionalSeconds": "2019-03-14T12:54:58.28",
  "customDate": "03/12/2019 11:13:00"
}
"""
let jsonDecoder = JSONDecoder()
let jsonData = Data(json.utf8)
do {
    let parsedDate = try jsonDecoder.decode(DateWrapper.self, from: jsonData)
    print(parsedDate)
} catch {
    print(error)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment