Включить функцию преобразования даты внутри расширения DateFormatter

#swift #watchkit #dateformatter

#swift #watchkit #dateformatter

Вопрос:

Расширение форматирует дату API, затем функция конвертера преобразует ее в формат, который мне нравится.

Код работает, но вызов кажется подробным. Это то, что можно переработать? Могу ли я объединить эти два?

Казалось логичным сделать DateFormatter из convertDateFormater функции iso8601Full свойство. Ошибок не было, но попытка вызова не сработала.

Пожалуйста, отправьте ответ с кодом, чтобы я мог пометить его правильно.

 extension DateFormatter {
    static let iso8601Full: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    }()
}

    func convertDateFormater(date: String) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let date = dateFormatter.date(from: date)
        dateFormatter.dateFormat = "dd/MM/yyyy"
        return  dateFormatter.string(from: date!)
    }
  

вызов

 row.creationDateLabel.setText("(convertDateFormater(date: DateFormatter.iso8601Full.string(from: value.creationDate)))")
  

Ответ №1:

Вы создаете форматеры даты внутри своего метода, что может быть дорогостоящим. Возможно, вы захотите сохранить оба внутри static:

 extension DateFormatter {
    static let iso8601Full: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    }()

    static let dateOnly: DateFormatter = {
         let formatter = DateFormatter()
         formatter.dateFormat = "dd/MM/yyyy"
         return formatter
    }()

    static func string(iso string: String) -> String {
        let date = DateFormatter.iso8601Full.date(from: string)!
        return  DateFormatter.dateOnly.string(from: date)
    }
}
  

И тогда вы можете сделать:

 row.creationDateLabel.setText(DateFormatter.string(iso: value.creationDate))
  

Это более лаконично и позволяет избежать избыточного создания экземпляров форматеров.

Лично я бы использовал dateFormat вместо того, чтобы использовать dateOnly inside dateStyle , поэтому строка даты (предположительно показываемая в пользовательском интерфейсе) правильно локализована, но вы можете делать все, что хотите.

(Кстати, я ввел это на своем телефоне, поэтому приношу извинения, если есть какие-либо синтаксические ошибки, но, надеюсь, это иллюстрирует основную идею.)


Если creationDate это уже Date , то вам не нужно ничего из этого, специфичного для iso. Я основывал свой ответ на вашем методе, который принимал String в качестве параметра. Если это уже Date , то это просто:

 row.creationDateLabel.setText(DateFormatter.dateOnly.string(from: value.creationDate))
  

Комментарии:

1. Спасибо. Я получаю Cannot convert value of type 'Date' to expected argument type 'String' вызов label. Я не уверен, но я не думаю, что это потому, что мой CreationDate в моей модели имеет тип Date.

2. Если это уже есть Date , то вам не нужно ничего из этого, специфичного для iso. Я основывал свой ответ на вашем методе, который принимал String в качестве параметра. Если это уже есть Date , то смотрите Пересмотренный ответ выше.

3. Я использую formatter.dateStyle = .short так, как вы предложили. Это приятно.