我需要用JSON有效负载解析以下日期,它几乎是ISO8601格式的。
"2020-06-05 14:52:54 UTC"为了与ISO8601保持一致,需要稍微修改一下。
"2020-06-05T14:52:54Z"这是超级恼人,因为我现在必须制定一个客户日期解码策略。
static func make() -> JSONDecoder {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
// decoder.dateDecodingStrategy = .iso8601
decoder.dateDecodingStrategy = .custom({ decoder in
let container = try decoder.singleValueContainer()
let dateStr = try container.decode(String.self)
guard let date = formatter.date(from: dateStr) else {
preconditionFailure("Unexpected date format.")
}
return date
})
return decoder
}我无法控制数据源。在这种情况下,我能做些什么来避免定制解码策略吗?
发布于 2022-09-05 12:45:59
由于您似乎只想使用DateFormatter来解析日期字符串,所以请使用formatted策略。
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzzz"
// or
// formatter.dateFormat = "yyyy-MM-dd HH:mm:ss 'UTC'"
// formatter.timeZone = .init(identifier: "UTC")
formatter.locale = Locale(identifier: "en_US_POSIX")
decoder.dateDecodingStrategy = .formatted(formatter)发布于 2022-09-05 13:22:47
清除者回答的另一种方法是编写DateFormatter的扩展
extension DateFormatter {
static let almostISO8601Formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
return formatter
}()
}那么您的make()函数就会变成
static func make() -> JSONDecoder {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(.almostISO8601Formatter)
return decoder
}还可以考虑将make() (具有更有意义的名称)放在JSONDecoder的扩展中
发布于 2022-09-05 12:47:56
您可以将输入映射到iso8601中,以使用现有的解码器:
func iso8601ify(_ str: String) -> String {
str.split(separator: " ")
.prefix(2)
.joined(separator: "T")
.appending("Z")
}当然,这个例子没有错误处理
https://stackoverflow.com/questions/73609311
复制相似问题