swift - 谁以正确的方式实施 ISO8601?斯威夫特还是春天?
问题描述
Spring 框架中使用的 Jackson 序列化器的默认行为如下:(来自 spring-data-rest 源代码):
/**
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSZ},
* e.g. "2000-10-31T01:30:00.000-05:00".
* <p>This is the default if no annotation value is specified.
*/
所以这种格式的一个例子可能是2019-03-20T11:18:46.000+0000
. Swift 也有 ISO8601 解码器,但事实上,对于 Swift,这个字符串只是因为毫秒而具有无效格式。如果去掉毫秒部分,swift可以成功反序列化字符串。
struct Test: Codable {
let createdAt: Date
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let data2 = "{\"createdAt\": \"2018-12-05T14:05:35.000+0000\"}".data(using: .utf8)!
let decoded2 = try! decoder.decode(Test.self, from: data2)
Swift 指的是 RFC 3339 https://www.ietf.org/rfc/rfc3339.txt并没有提到毫秒。我的问题是 - 那么什么格式是正确的呢?如果某些东西是 ISO 格式,应该严格定义,我通常不希望编写自定义反序列化器 (swift) 或定义用于序列化的自定义模式 (spring)。
解决方案
您应该设置 iso8601 选项。您可以使用 ISO8601DateFormatter 来完成。
struct Test: Codable {
let createdAt: Date
}
enum CustomDateDecodingStrategy {
private static let formatter: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [
.withFullDate,
.withFullTime,
.withTimeZone,
.withFractionalSeconds
]
return formatter
}()
static func decode(_ decoder: Decoder) throws -> Date {
let container = try decoder.singleValueContainer()
let dateStr = try container.decode(String.self)
if let date = formatter.date(from: dateStr) {
return date
} else {
throw NSError(domain: "date", code: -1, userInfo: nil)
}
}
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(CustomDateDecodingStrategy.decode)
let data2 = "{\"createdAt\": \"2018-12-05T14:05:35.000+0000\"}".data(using: .utf8)!
let decoded2 = try! decoder.decode(Test.self, from: data2)
推荐阅读
- r - ggplot2 绘图功能
- android - 需要访问联系人的权限才能将联系人信息从应用程序保存到本机联系人?
- flutter - 颤动:文本字段中的 textDirection 不起作用
- hive - Impala/Hive - 汇总调整代码的金额
- google-apps-script - 表格:未捕获的类型错误:google.script.run.withSuccessHandler(...).is not a function
- url - root-relative 和 protocol-relative url 路径有什么区别?
- excel - 在 VBA 中使用 IF
- node.js - res.cookie(名称,值);不设置 cookie (Express/NodeJs)
- keycloak - 通过 Standalone.sh 在与 localhost 不同的地址上启动 Keycloak 服务器
- r - 在绘图区域外添加文本