|
import Foundation
|
|
|
|
public extension JSONDecoder.DateDecodingStrategy {
|
|
nonisolated(unsafe) private static let dateFormatter: ISO8601DateFormatter = {
|
|
let formatter = ISO8601DateFormatter()
|
|
formatter.formatOptions = [.withInternetDateTime]
|
|
return formatter
|
|
}()
|
|
|
|
nonisolated(unsafe) private static let dateFormatterWithFractionalSeconds: ISO8601DateFormatter = {
|
|
let formatter = ISO8601DateFormatter()
|
|
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
|
|
return formatter
|
|
}()
|
|
|
|
static let iso8601WithOptionalFractionalSeconds: Self = {
|
|
return .custom { (decoder) -> Date in
|
|
let container = try decoder.singleValueContainer()
|
|
let dateString = try container.decode(String.self)
|
|
|
|
// Workaround to work with both, fractional seconds and whole seconds.
|
|
|
|
// Try whole seconds first:
|
|
|
|
if let date = dateFormatter.date(from: dateString) {
|
|
return date
|
|
}
|
|
|
|
// If it fails, try fractional:
|
|
|
|
if let date = dateFormatterWithFractionalSeconds.date(from: dateString) {
|
|
return date
|
|
}
|
|
|
|
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Could not decode date from \(dateString).")
|
|
}
|
|
}()
|
|
}
|