Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Преобразование строки JSON yyyy-mm-ddthh:mm:ssz в читаемый формат в Swift?

Автор вопроса: nickcodingОтветов: 2

Я пытаюсь преобразовать строку, переданную в мое приложение, в виде строки в формате вопроса (гггг-мм-ддчч:мм:ссз) во что-то понятное пользователю. Я попытался создать переменную для форматирования даты:

var dateFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
    return formatter
}

а затем я попытался использовать его следующим образом:

Text("\(self.dateFormatter.date(from: self.dateToConvert))")

где dateToConvert - это передаваемая строка JSON. Ошибка, которую я получил, заключалась в том, что метод экземпляра "appendInterpolation" требует этой "Даты?" соответствовать '_FormatSpecified'. Есть идеи, как это сделать правильно?

  • Не заключайте Z в одинарные кавычки в формате даты. Z предназначен для того, чтобы указать форматировщику даты анализировать часовой пояс как часть даты. Duncan C 10.08.2020
  • SwiftUI.Text ожидает, что вы дадите ему значение (как Date) и отформатируете отдельно. Он сам отформатирует дату. hackingwithswift.com/quick-start/ Свифтуи/ Alexander 10.08.2020

swiftdate-format

Ответы

Ответ 1 · рейтинг 1 · pawello2222

Сначала вам нужно установить удобный формат даты для вашего форматтера. Затем преобразуйте объект Date обратно в String:

dateFormatter.setLocalizedDateFormatFromTemplate("yyyyMMdd")
let text = dateFormatter.string(from: convertedDate)

И использовать его в Text напрямую:

Text(text)

ИЗМЕНИТЬ

Вот простая демонстрация того, как вы можете разобрать и отобразить Date:

struct ContentView: View {
    @State var date: Date? = Date()

    // by making `it static let` it is only computed once
    static let inputDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(abbreviation: "UTC")
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" // <- do not escape `Z` (time zone)
        return formatter
    }()

    static let outputDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.setLocalizedDateFormatFromTemplate("yyyyMMddHHmmss")
        return formatter
    }()

    // handling of optional `Date`
    var formattedDate: String {
        guard let date = date else { return "Date is nil" }
        return Self.outputDateFormatter.string(from: date)
    }

    var body: some View {
        Text(formattedDate)
            .onAppear(perform: parseDate)
    }

    func parseDate() {
        let dateStr = // your date as `String`
        if let date = Self.inputDateFormatter.date(from: dateStr) {
            self.date = date
        } else {
            print("invalid date")
        }
        // alternatively if you don't care about errors:
        // date = Self.dateFormatter.date(from: dateStr)
    }
}

Ответ 2 · Duncan C

Функция DateFormatter date(from:) возвращает дату Optional. Если введенная вами строка недействительна, она вернет ноль.

Как и во многих других случаях в Swift, вам нужно написать код для обработки nil. Один из способов сделать это:

let dateFromString = dateFormatter.date(from: self.dateToConvert) ?? "invalid"
print("Converted date = \(dateFromString)")

Поочередно:

if let dateFromString = dateFormatter.date(from: self.dateToConvert) {
    print("Converted date = \(dateFromString)")
} else {
    print("Date string is in an invalid format.")
}

Также обратите внимание, что когда вы регистрируете Date, оно будет отображаться в формате UTC, поэтому часовой пояс, вероятно, будет отличаться от вашего местного часового пояса. Если вы хотите отобразить его в местном часовом поясе, вам необходимо предпринять дополнительные шаги.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы