Изменить формат даты iso-8601 на пользовательский формат

У меня есть файл JSON анализируется с помощью JSONDecoder(). Однако я получаю переменную метку времени типа Date в формате iso-8601 ("гггг-мм-дд'т'хч: мм: сс.SSSXXXXX"), но, на мой взгляд, я хочу отобразить ее в произвольном формате: "дд / мм / гг чч: мм: сс".

Я написал следующий код, но я получаю ноль для метки времени, и, кроме того, я предполагаю, что "дата" не является правильным типом для использования, когда метка времени приходит в формате ISO-8601:

Ошибка json: typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "timestamp", intValue: nil)], debugDescription: "Ожидается декодировать Double, но вместо этого нашел строку / данные.", underError: nil))

swift4

import UIKit

enum Type : String, Codable {
    case organizational, planning
}

// structure from json file
struct News: Codable{
    let type: Type
    let timestamp: Date //comes in json with ISO-8601-format
    let title: String
    let message: String

    enum  CodingKeys: String, CodingKey { case type, timestamp, title, message}

    let dateFormatter : DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd/MM/yy HH:mm:ss"  // change format ISO-8601 to dd/MM/yy HH:mm:ss
        return formatter
    }()

    var dateString : String {
        return dateFormatter.string(from:timestamp) // take timestamp variable of type date and make it a string -> lable.text
    }
}

1 ответ

Решение

Когда вы декодируете Date декодер ожидает метку времени UNIX (Double) по умолчанию это то, что говорит вам сообщение об ошибке.

Однако вы действительно можете декодировать строку ISO8601 как Date если вы добавите decoder.dateDecodingStrategy = .iso8601 но это декодирует только стандартные строки ISO8601 без миллисекунд.

Есть два варианта:

  1. Добавить formatteddateDecodingStrategy с DateFormatter,

    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
    let decoder = JSONDecoder() 
    decoder.dateDecodingStrategy = .formatted(dateFormatter)
    try decoder.decode(...
    
  2. декларировать timestamp как

    let timestamp: String
    

    и преобразовать строку назад и вперед с двумя форматерами или двумя форматами даты в dateString,

Другие вопросы по тегам