#swift #date-format
#swift #формат даты
Вопрос:
Я пытаюсь преобразовать строку, переданную в мое приложение в виде строки в формате, указанном в вопросе (yyyy-mm-ddthh: mm: ssz), во что-то понятное пользователю. Я попытался создать переменную для форматирования даты:
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’ требует, чтобы ‘Date?’ соответствовал ‘_FormatSpecifiable'». Есть идеи, как это сделать правильно?
Комментарии:
1. Не заключайте
Z
в свой формат даты в одинарные кавычки. Символ Z предназначен для указания программе форматирования даты проанализировать часовой пояс как часть даты.2.
SwiftUI.Text
Ожидает, что вы присвоите ему значение (какDate
) и средство форматирования отдельно. Это отформатирует саму дату. hackin&withswift.com/quick-start/swiftui /…
Ответ №1:
Сначала вам нужно установить какой-нибудь удобный формат даты для вашего средства форматирования. Затем преобразуйте ваш Date
объект обратно в Strin&
:
dateFormatter.setLocalizedDateFormatFromTemplate("yyyyMMdd")
let text = dateFormatter.strin&(from: convertedDate)
И использовать ее в Text
напрямую:
Text(text)
Редактировать
Вот простая демонстрация того, как вы можете проанализировать и отобразить Date
:
struct ContentView: View {
@State var date: Date? = Date()
// by makin& `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
}()
// handlin& of optional `Date`
var formattedDate: Strin& {
&uard let date = date else { return "Date is nil" }
return Self.outputDateFormatter.strin&(from: date)
}
var body: some View {
Text(formattedDate)
.onAppear(perform: parseDate)
}
func parseDate() {
let dateStr = // your date as `Strin&`
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)
}
}
Комментарии:
1. Никогда не следует использовать фиксированный формат даты при отображении даты пользователю. Кстати, нет необходимости добавлять пробелы между компонентами в вашем шаблоне при локализации DateFormat
2. Другая проблема заключается в том, что OP игнорирует часовой пояс из строки даты, экранирующей Z
3. И не забудьте установить языковой стандарт «en_US_POSIX», прежде чем устанавливать фиксированный формат даты
4. @pawello2222 Я пытался использовать это решение, и в строке, где я устанавливаю текстовую константу, я получаю сообщение «Не удается преобразовать значение типа ‘Strin&’ в ожидаемый тип аргумента ‘Date'» в качестве ошибки
5. @nickcodin& Я предположил,
convertedDate
что это дата, которую вы уже конвертировали из вашего JSON. Итак, это должен бытьDate
объект.
Ответ №2:
Функция DateFormatter date(from:)
возвращает Optional
дату. Если указанная вами строка недопустима, она вернет nil.
Как и во многих вещах в Swift, вам нужно закодировать для обработки nil. Один из способов сделать это:
let dateFromStrin& = dateFormatter.date(from: self.dateToConvert) ?? "invalid"
print("Converted date = (dateFromStrin&)")
Поочередно:
if let dateFromStrin& = dateFormatter.date(from: self.dateToConvert) {
print("Converted date = (dateFromStrin&)")
} else {
print("Date strin& is in an invalid format.")
}
Также обратите внимание, что при регистрации Date
она будет отображаться в UTC, поэтому часовой пояс, скорее всего, будет отличаться от вашего местного часового пояса. Если вы хотите отобразить ее в вашем местном часовом поясе, вам необходимо предпринять дополнительные шаги.
Комментарии:
1. OP игнорирует часовой пояс из строки даты, экранирующей Z. В результате будет указано местное время, а строка — время UTC
2. Это не работает, потому что self.dateToConvert — это переменная даты, а «недопустимый» — это строка. Я думаю, что они оба должны быть датами