Использование NumberFormatter в DateFormatter - PullRequest
3 голосов
/ 17 июня 2020

Я пытаюсь отформатировать свой Date(), чтобы он выглядел как Saturday, June 12th • 5PM - 12PM. Я смог решить большую часть этого с помощью следующего DateFormatter():

var date_formatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "EEEE, MMMM d • HHa - HHa"
    return formatter
}

, что приводит к Saturday, June 12 • 5PM - 12PM

Проблема, с которой я столкнулся, заключается в том, чтобы понять, как добавить порядковый суффикс (например, 12 -> 12-й). Я кое-что видел на NumberFormatter(), но не совсем уверен, как их объединить.

EDIT: закончилось создание двух форматов для 5PM - 12PM logi c.

Это выглядит так:

var start_time_formatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "EEEE, MMMM d • HHa -"
        return formatter
    }

    var end_time_formatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "HHa"
        return formatter
    }

со следующим отображением в представлении:

Text("\(self.create_event_vm.start_time, formatter: self.start_time_formatter) \(self.create_event_vm.end_time, formatter: self.end_time_formatter)")

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

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Первый суффикс дня, вы можете создать функцию ниже

func getDaySuffix(from date: Date) -> String {  
    switch Calendar.current.component(.day, from: date) {
    case 1, 21, 31: return "st"
    case 2, 22: return "nd"
    case 3, 23: return "rd"
    default: return "th"
    }
}

и объединить с вашими кодами:

let startDate = Date()
let endDate = Calendar.current.date(byAdding: .hour, value: 5, to: startDate)!

var startTimeFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "EEEE, MMMM d'\(getDaySuffix(from: startDate))' • ha - "
    return formatter
}

var endTimeFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "ha"
    return formatter
}

let startDateResult = startTimeFormatter.string(from: startDate) // "Thursday, June 18th • 2AM - "
let endDateResult = endTimeFormatter.string(from: endDate) // "7AM"
let finalResult = startDateResult + endDateResult // "Thursday, June 18th • 2AM - 7AM"
0 голосов
/ 18 июня 2020

Сначала полезное расширение Int+Ordinal.swift:

extension Int {

    /// `Int` ordinal suffix
    enum Ordinal: String {

        /// Suffix for numbers ending in `1` except 11
        case st = "st"

        /// Suffix for numbers snding in `2` except 12
        case nd = "nd"

        /// Suffix for numbers ending in `3` except 13
        case rd = "rd"

        /// Suffix otherwise 
        case th = "th"
    }

    /// Get `Ordinal` from `Int` `self`
    var ordinal: Ordinal {
        var mod = self % 100
        if mod == 11 || mod == 12 || mod == 13 {
            return .th
        } else {
            mod = mod % 10
            if mod == 1 {
                return .st
            } else if mod == 2 {
                return .nd
            } else if mod == 3 {
                return .rd
            } else {
                return .th
            }
        }
    }
}

Затем используйте это расширение и DateFormatter:

func string(from startDate: Date, to endDate: Date) -> String {
    let formatter = DateFormatter()

    // weekdayMonth
    formatter.dateFormat = "EEEE, MMMM"
    let weekdayMonth = formatter.string(from: startDate)

    // day
    formatter.dateFormat = "d"
    var day = formatter.string(from: startDate)
    if let dayValue = Int(day) {
        day += dayValue.ordinal.rawValue
    }

    // timeFrom
    formatter.dateFormat = "ha"
    let timeFrom = formatter.string(from: startDate)

    // timeTo
    let timeTo = formatter.string(from: endDate)

    return "\(weekdayMonth) \(day) • \(timeFrom) - \(timeTo)"
}

Запуск:

let dateString = string(from: Date(), to: Date().addingTimeInterval(3600 * 4))
print(dateString) // "Wednesday, June 17th • 11PM - 3AM"

Хотя я думаю, что в этом примере вы не хотите, чтобы это произошло на следующий день! :)

0 голосов
/ 17 июня 2020

Вы идете по неправильному пути. Вам нужно создать DateInterval и использовать его DateIntervalFormatter для отображения его пользователю. Обратите внимание, что 12 вечера это уже другой день, поэтому ваше представление интервала дат неверно:

let dateA = DateComponents(calendar: .current, year: 2020, month: 6, day: 12, hour: 17, minute: 0).date!
let dateB = DateComponents(calendar: .current, year: 2020, month: 6, day: 13, hour: 0, minute: 0).date!
let di = DateInterval(start: dateA, end: dateB)
let dif = DateIntervalFormatter()
dif.dateTemplate = "EEEEMMMMdh"
dif.string(from: di)   // "Friday, June 12, 5 PM – Saturday, June 13, 12 AM"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...