考虑以下类型:
public struct DocumentDate: Codable {
/// Year component of the date, Integer with no limitation on the range.
public let year: Int
/// Month component of the date, Integer from 1 to 12.
public let month: Int
/// Day component of the date, Integer from 1 to 31.
public let day: Int
}
将
Codable
更具体地说 Decodable
协议支持合并到此类型中以解码 ISO 8601 兼容日期类型的最简单方法是什么:
"2012-01-13"
理想情况下,我希望在初始化程序中得到一个
String
解码,然后我就可以按照我的意愿解析它。实施这种支持的最佳策略是什么?
我知道我可以使用 dateDecodingStrategy 但这是将
String
解码为 Date
。我的类型实际上不是 Date
,而是自定义类型,所以这就是挑战所在。
我的建议是实现
init(from:)
并使用正则表达式解析日期字符串
public struct DocumentDate: Decodable {
/// Year component of the date, Integer with no limitation on the range.
public let year: Int
/// Month component of the date, Integer from 1 to 12.
public let month: Int
/// Day component of the date, Integer from 1 to 31.
public let day: Int
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
guard let match = dateString.wholeMatch(of: /(\d{4})-(\d{2})-(\d{2})/)?.output else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Wrong date format")
}
year = Int(match.1)!
month = Int(match.2)!
day = Int(match.3)!
}
}
以及如何使用它的示例
let jsonString = """
{"date":"2012-01-13"}
"""
struct Test: Decodable {
let date: DocumentDate
}
do {
let result = try JSONDecoder().decode(Test.self, from: Data(jsonString.utf8))
print(result)
} catch {
print(error)
}