As shown in the possible duplicate post I have already mentioned in comments, you need to create a custom date decoding strategy:
First create your date formatter for parsing the date string (note that this assumes your date is local time, if you need UTC time or server time you need to set the formatter timezone property accordingly):
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
}()
}
Then create a custom decoding strategy to try all possible date decoding strategy you might need:
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)")
}
}
}
Playground testing:
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"