Как отобразить дату человеческим языком, например «Сегодня в xx: xx вечера», «Вчера в xx: xx утра»?

#ios #nsdate #swift #nsdateformatter

#iOS #nsdate #swift #nsdateformatter

Вопрос:

У меня свидание «2014-07-02 20:57:38 0000» и я хочу отформатировать его как «Сегодня в 8:57 вечера». Я хочу, чтобы, если строка была вчерашней, то отображала ее как «Вчера в 9:00 утра». Если это ни сегодня, ни вчера, просто покажите фактическую дату, например «27/6 в 7: 53 вечера».

Я смог получить время в формате «8: 57 утра» с помощью приведенного ниже кода.

             var formatter : NSDateFormatter = NSDateFormatter()
            formatter.dateFormat = "h:mm a"

            // message.createdAt is the date
            let dateString = formatter.stringFromDate(message.createdAt)
            println(dateString)

            //output = 8:57 AM
  

Однако, когда я использую следующий код, он возвращает пустую строку.

             var formatter : NSDateFormatter = NSDateFormatter()
            formatter.dateFormat = "h:mm a"
            formatter.doesRelativeDateFormatting = true  //<-- This doesn't work

            let dateString = formatter.stringFromDate(message.createdAt)
            println(dateString)

            //output = (nothing, its a blank string)
  

Как мне заставить это работать и отобразить «Сегодня» или «Вчера» в Swift?

Ответ №1:

Причина, по которой оно пустое, заключается в том, что в вашем формате даты есть только компоненты времени. В сочетании с .doesRelativeDateFormatting это дает вам пустую строку. Если вам нужен этот пользовательский формат времени, я думаю, вам нужны отдельные форматеры для даты и времени:

 let now = NSDate()

let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.doesRelativeDateFormatting = true

let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "h:mm a"

let time = "(dateFormatter.stringFromDate(now)), (timeFormatter.stringFromDate(now))"
println(time)      // prints "Today, 5:10 PM"
  

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

1. На самом деле вам нужен только один. Вы можете сделать это следующим образом: var formatter : NSDateFormatter = NSDateFormatter() formatter.dateStyle = NSDateFormatterStyle. ShortStyle formatter.timeStyle = NSDateFormatterStyle. ShortStyle formatter.does relativedateformatting = true var dateString = formatter.stringFromDate(NSDate())

2. Это решение не обеспечивает правильное время для большинства часовых поясов и летнего / зимнего времени. Смотрите решение Incyc ниже.

Ответ №2:

В Swift 5.1 ссылка на API разработчика Apple указывает на DateFormatter dateFormat свойство:

Вы должны устанавливать это свойство только при работе с представлениями в фиксированном формате, как описано в разделе Работа с представлениями даты в фиксированном формате. Для видимых пользователем представлений следует использовать свойства dateStyle и timeStyle или метод setLocalizedDateFormatFromTemplate(_:), если желаемый формат не может быть достигнут с использованием предопределенных стилей; оба эти свойства и этот метод предоставляют локализованное представление даты, подходящее для отображения пользователю.


Следующий пример кода Playground показывает, как отобразить ваши даты в желаемом формате, используя dateStyle, timeStyle и doesRelativeDateFormatting свойства:

 import Foundation

let now = Date() // 2019-08-09 12:25:12  0000
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: now)! // 2019-08-08 12:25:12  0000
let aWeekAgo = Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: now)! // 2019-08-02 12:25:12  0000

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true

let nowString = dateFormatter.string(from: now)
print(nowString) // prints: Today at 2:25 PM

let yesterdayString = dateFormatter.string(from: yesterday)
print(yesterdayString) // prints: Yesterday at 2:25 PM

let aWeekAgoString = dateFormatter.string(from: aWeekAgo)
print(aWeekAgoString) // prints: August 2, 2019 at 2:25 PM
  

Ответ №3:

Попробуйте это в Swift:

 let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dateFormatter.doesRelativeDateFormatting = true

let date = Date()
let dateString = dateFormatter.string(from:date)
  

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

1. В нем говорится, что «У NSDateFormatter нет элемента с именем localizedStringFromDate»

2. @HenryNgan Извините, не понял, что это метод класса, исправленный в edit now