Почему следующий код сортировки времени прерывается для устройств, использующих 24-часовые часы? - PullRequest
0 голосов
/ 26 июня 2019

Извиняюсь, если это очевидный вопрос, но я какое-то время назад создал приложение со Swift и периодически обновлял его, но каждый раз, возвращаясь к нему, я довольно ржавый.

У меня есть следующий код, который сортирует элементы по времени:

let dateFormat = DateFormatter()
dateFormat.dateFormat = "h:mm a"

items = items.sorted(by: {dateFormat.date(from: $0.time)! < dateFormat.date(from: $1.time)!})

Это нормально работает для устройств, использующих 12-часовое время, но выдает ошибку для устройств, использующих 24-часовое время (и, возможно, если в локали используется 12-часовое время, но не AM / PM?).

Изучив различные вопросы о переполнении стека и документацию для разработчиков, а также путем проб и ошибок, я обнаружил, что добавление следующей строки кода устраняет проблему:

dateFormat.locale = Locale(identifier: "en_US")

Если я сортирую по времени и указал свой формат даты, почему это имеет значение, какую локаль использует устройство? Когда DateFormatter документация говорит:

... обеспечивает представление указанной даты, которая является подходящей для данного региона.

Означает ли это, что в каждом устройстве форматирования даты должен быть указан языковой стандарт, и, поскольку я не указал его в исходном коде, он принял языковой стандарт устройства? Следовательно, если пользователь использовал локаль, которая не поддерживает 12-часовые часы, он выдал ошибку?

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Подход ...

Поскольку у вас есть два возможных формата, вам нужно два форматера ...

let format12 = DateFormatter()
format12.dateFormat = "h:mm a"
// Fix the possible formatting and avoid issues with the local and parsing
format12.locale = Locale(identifier: "en_US_POSIX")

let format24 = DateFormatter()
format24.dateFormat = "H:mm"
format24.locale = Locale(identifier: "en_US_POSIX")

Теперь вам нужно проанализировать ваш ввод в значения даты ...

var items: [String] = ["1:00 PM", "4:00 PM", "13:00", "16:00"]

var dates: [Date?] = items.map {
    if let value = format24.date(from: $0) { return value }
    else if let value = format12.date(from: $0) { return value }
    return nil
}

И сортируй это ...

dates.sort {
    guard let lhs = $0, let rhs = $1 else { return true }
    return lhs < rhs
}

Теперь вышеприведенное предполагает, что некоторые значения могут быть nil, и предпринимает соответствующие действия.

Теперь вы можете вместо этого использовать compactMap, чтобы удалить возможные значения nil, например ...

var dates: [Date] = items.compactMap {
    if let value = format24.date(from: $0) { return value }
    else if let value = format12.date(from: $0) { return value }
    return nil
}

dates.sort {
    guard let lhs = $0, let rhs = $1 else { return true }
    return lhs < rhs
}

dates.sort { $0 < $1 }

Я выбросил все это на игровую площадку, и у меня нет проблем

Примечание к сведению ...

Если вы получаете nil значения с помощью любого из двух форматеров, вам необходимо более внимательно посмотреть на значения и определить, как они не соответствуют шаблону форматеров, и предпринять соответствующие действия для его исправления

0 голосов
/ 27 июня 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...