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可以成功反序列化字符串。
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)。
答案 0 :(得分:1)
您应该设置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)
答案 1 :(得分:1)
the ISO8601 2016 draft的第23页:
如果对于特定的应用程序是必需的,则可以包括小时,分钟或秒的十进制小数。如果包括小数部分,则应省略低阶时间元素(如果有的话),并且小数部分应从整数部分除以ISO 31-0中指定的小数点,即逗号[,]或句号[ 。]。其中,逗号是首选符号。如果数字的大小小于1,则根据3.6,小数点后应带有两个零。
因此2018-12-05T14:05:35.000
是合法的。尽管RFC 3339并没有提到毫秒的名称,但它确实提到了“分数”,例如:
以下定义的格式仅包含一个很少使用的选项: 几分之一秒。预计仅将由 需要严格订购日期/时间戳的应用程序或 具有非同寻常的精度要求。
和
ISO 8601还要求(在5.3.1.3节中)小数部分 如果小于1,则以“ 0”开头。 ISO 8601的附件B.2 给出了小数点后没有“ 0”的示例。 该语法假设第5.3.1.3节是正确的,并且附件B.2是 错误。