Данные повреждены Ошибка декодирования ISO8601 Swift 4

У меня есть следующий код Swift.

class Person: Codable {
    var born: Date
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
    let person = try decoder.decode(Person.self, from: "{\"born\": \"2017-12-04T23:24:09.853Z\"}".data(using: .utf8)!)
} catch {
    print(error)
}

Я ожидаю, что это вернет объект Person с датой born 2017-12-04T23:24:09.853Z (из того, что я могу понять, это полностью действительная дата ISO8601).

Вместо этого я получаю сообщение об ошибке dataCorrupted(Swift.DecodingError.Context(codingPath: [__lldb_expr_1.Person.(CodingKeys in _1Q81646826320N3Z86BD5V078M06H287).born], debugDescription: "Expected date string to be ISO8601-formatted.", underlyingError: nil)).

Согласно Swift, похоже, что моя строка даты не ISO8601-formatted, хотя я вполне уверен, что это так (согласно этот пакет NPM и этот ответ).

Что я здесь делаю неправильно?


person Charlie Fish    schedule 05.12.2017    source источник
comment
Дата ISO8601 будет иметь часовой пояс как +/-XX:XX.   -  person rmaddy    schedule 05.12.2017
comment
Отлично, спасибо @rmaddy, тогда придется кое-что реструктурировать. Спасибо за вашу помощь.   -  person Charlie Fish    schedule 05.12.2017
comment
@rmaddy Любая причина, по которой это говорит, что моя строка соответствует ISO-8601?   -  person Charlie Fish    schedule 05.12.2017
comment
@rmaddy Вот почему я думал, что это формат ISO-8601. Прежде чем перейти к моему коду Swift, я запускаю .toISOString() в Javascript, и, согласно этой ссылке, он должен дать мне строку ISO-8601.   -  person Charlie Fish    schedule 05.12.2017
comment
@CharlieFish Проблема не в Z, а в долях секунды. Проверьте это « title = «как преобразовать строку даты с необязательными дробными секундами, используя кодирование в s»> stackoverflow.com/questions/46458487/   -  person Leo Dabus    schedule 05.12.2017
comment
Вы можете проверить ожидаемый формат даты, создав строковое представление даты, используя строку метода ISO8601DateFormatter (из: даты), которая возвращает Z для часового пояса UTC "2017-12-05T03:53:36Z"   -  person Leo Dabus    schedule 05.12.2017
comment
Проблема в том, что если вы попытаетесь установить для свойства formatOptions объекта ISO8601DateFormatter значение [.withFractionalSeconds], произойдет сбой libc++abi.dylib: завершение работы с необработанным исключением типа NSException. Поэтому вам нужно будет создать собственный модуль форматирования даты для анализа строки даты ISO8601, если она содержит дробные секунды.   -  person Leo Dabus    schedule 05.12.2017
comment
@CharlieFish Лучший вариант — использовать Double Date().timeIntervalSinceReferenceDate вместо строки и установить dateDecodingStrategy в .deferredToDate. decode(Person.self, from: Data("{\"born\": 534139975.486094}".utf8))   -  person Leo Dabus    schedule 05.12.2017