Подтвердить что ты не робот

Дата/время Приближение естественного языка в Swift

Я пытаюсь преобразовать дату, отформатированную в формате UTC, из API в удобный для восприятия формат с использованием Swift.

Я ищу что-то вроде следующего:

2015-07-14T13: 51: 05.423Z

к

Около двух недель назад

Каков наилучший подход к этому в Swift? Хотя оптимально это может напрямую форматировать строки, я понимаю, что это, вероятно, потребует лить строку в объект NSDate.

Любая помощь будет принята с благодарностью.

EDIT: мой вопрос был идентифицирован как возможный дубликат другого вопроса. Решение Tom ниже написано для Swift и намного более элегантно, чем создание нового метода в отношении моей ситуации.

4b9b3361

Ответ 1

Вам нужно два шага. Сначала преобразуйте строку даты в NSDate:

let dateString = "2015-07-14T13:51:05.423Z"

let df = NSDateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = df.dateFromString(dateString)

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

Затем используйте NSDateComponentsFormatter для получения нужной строки:

let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Full
formatter.includesApproximationPhrase = true
formatter.includesTimeRemainingPhrase = false
formatter.allowedUnits = NSCalendarUnit.WeekOfMonthCalendarUnit

if let pastDate = date {
    let dateRelativeString = formatter.stringFromDate(pastDate, toDate: NSDate())
}

Сегодня 28 июля, поэтому результат для этой строки - "Около 2 недель". Атрибут allowedUnits - это поле бит, поэтому вы можете указать столько типов единиц, сколько хотите.

Ответ 2

Как отмечает Том Харрингтон, вы можете создать разговорное представление момента или временного интервала с помощью NSDateComponentsFormatter.

Однако, если вы хотите сделать именно то, что задает вопрос в своем примере, что должно привести к разговорной передаче момента в прошлом относительно текущего момента, например, для пользовательского интерфейса, ориентированного на сроки, как NSDateComponentsFormatter не подходит. Как сказано в документации для stringFromTimeInterval(_:), значение временного интервала "должно быть конечным числом". Отрицательные числа обрабатываются как положительные числа при создании строки. "

Насколько я могу судить, лучшим выбором является TTTTimeIntervalFormatter, автономный класс в Mattt Thompson FormatterKit.

Я создал игровую площадку Xcode 7, RelativeDatePlayground, которая сравнивает выходы вывода NSDateFormatter с TTTTimeIntervalFormatter. Вот таблица, показывающая выходные данные для разных относительных времен в секундах. Как вы можете видеть, NSDateComponentsFormatter, похоже, не справляется с прошлыми моментами или настоящим моментом:

        -1488010 |               2 weeks ago |         -1 week remaining
        -1468800 |               2 weeks ago |         -1 week remaining
         -864000 |                1 week ago |       0 seconds remaining
          -86400 |                 1 day ago |          -1 day remaining
          -36000 |              10 hours ago |       -10 hours remaining
           -3600 |                1 hour ago |         -1 hour remaining
            -600 |            10 minutes ago |     -10 minutes remaining
             -60 |              1 minute ago |       -1 minute remaining
             -10 |            10 seconds ago |     -10 seconds remaining
              -1 |              1 second ago |       -1 second remaining
              -0 |                  just now |       0 seconds remaining
               0 |                  just now |       0 seconds remaining
               1 |         1 second from now |        1 second remaining
              10 |       10 seconds from now |      10 seconds remaining
              60 |         1 minute from now |        1 minute remaining
             600 |       10 minutes from now |      10 minutes remaining
            3600 |           1 hour from now |          1 hour remaining
           36000 |         10 hours from now |        10 hours remaining
           86400 |            1 day from now |           1 day remaining
          864000 |           1 week from now |          1 week remaining
         1468800 |          2 weeks from now |         2 weeks remaining
         1488010 |          2 weeks from now |         2 weeks remaining