具有多种日期格式的 JSONDecoder?
Posted
技术标签:
【中文标题】具有多种日期格式的 JSONDecoder?【英文标题】:JSONDecoder with multiple date formats? 【发布时间】:2020-08-24 07:52:40 【问题描述】:我有 2 种来自 api 的日期。我需要一起解码。但我没有找到任何解决方案。我需要在这段代码中添加"yyyy-MM-dd'T'HH:mm:ssZ"
格式。我该怎么做?
func run<T: Decodable>(_ request: URLRequest, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<Response<T>, Error>
return URLSession.shared
.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap result -> Response<T> in
self.dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(self.dateFormatter)
let value = try decoder.decode(T.self, from: result.data)
return Response(value: value, response: result.response)
.eraseToAnyPublisher()
【问题讨论】:
您能否澄清一下何时需要使用 format1 以及何时需要使用 format2?在同一个 JSON 中?在不同的?您是否确切知道它们在哪里使用,或者如果成功,您是否必须尝试?根据这一点,答案会有所不同。func run
为我的所有项目工作。但只有一种不同的 json 结果(不同的结构)返回不同的时间格式。我不想为一个结果添加更多功能。
视情况而定。你有参数JSONDecoder = JSONDecoder()
,我会把参数和它的dateFormatter放在这里,不会在trypMap()
中覆盖它,或者只是在你的方法中添加一个DateFormatter参数。
我可以把它放在哪里?当我不把它放在这里时,这个日期的json返回空白。
各种可能的想法:pastebin.com/sZse166b
【参考方案1】:
另一种方法是自定义dateDecodingStrategy
和ISO8601DateFormatter
,它能够根据给定的字符串指定日期格式
func run<T: Decodable>(_ request: URLRequest, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<Response<T>, Error>
return URLSession.shared
.dataTaskPublisher(for: request)
.receive(on: DispatchQueue.main)
.tryMap result -> Response<T> in
decoder.dateDecodingStrategy = .custom decoder -> Date in
let container = try decoder.singleValueContainer()
let dateFormatter = ISO8601DateFormatter()
let dateString = try container.decode(String.self)
if !dateString.hasSuffix("Z")
dateFormatter.formatOptions.remove(.withTimeZone)
if let isoDate = dateFormatter.date(from: dateString)
return isoDate
else
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Wrong Date Format")
let value = try decoder.decode(T.self, from: result.data)
return Response(value: value, response: result.response)
.eraseToAnyPublisher()
【讨论】:
谢谢它的工作,但这条线返回错误return dateFormatter.date(from: dateString) ?? throw DecodingError.dataCorruptedError(in: container, debugDescription: "Wrong Date Format")
我这样使用return dateFormatter.date(from: dateString)!
我不会那样做,如果日期格式与两种格式不匹配会导致崩溃。请查看编辑。【参考方案2】:
您可以通过实现init(from decoder: Decoder)
来实现自定义解码行为
https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types
【讨论】:
以上是关于具有多种日期格式的 JSONDecoder?的主要内容,如果未能解决你的问题,请参考以下文章