2016-09-06 5 views
13

Я пытаюсь решить, как решить, существует ли данная временная метка сегодня или +1/-1 дней. По сути, я хотел бы сделать что-то вроде этого (псевдокод)Swift - проверьте, есть ли временная метка вчера, сегодня, завтра или X дней назад

IF days_from_today(timestamp) == -1 RETURN 'Yesterday' 
ELSE IF days_from_today(timestamp) == 0 RETURN 'Today' 
ELSE IF days_from_today(timestamp) == 1 RETURN 'Tomorrow' 
ELSE IF days_from_today(timestamp) < 1 RETURN days_from_today(timestamp) + ' days ago' 
ELSE RETURN 'In ' + days_from_today(timestamp) + ' ago' 

Кардинально, хотя, это должно быть в Swift, и я изо всех сил с объектами NSDate/NSCalendar. Я начал с разработкой разницы во время, как это:

let calendar = NSCalendar.currentCalendar() 
let date = NSDate(timeIntervalSince1970: Double(timestamp)) 
let timeDifference = calendar.components([.Second,.Minute,.Day,.Hour], 
    fromDate: date, toDate: NSDate(), options: NSCalendarOptions()) 

Однако сравнивая таким образом не просто, потому что .Day отличается в зависимости от времени суток и меток времени. В PHP я бы просто использовал mktime для создания новой даты, основанной на начале дня (т. Е. mktime(0,0,0)), но я не уверен в самом простом способе сделать это в Swift.

Есть ли у кого-нибудь хорошая идея о том, как подойти к этому? Может быть, расширение NSDate или что-то подобное было бы лучше?

ответ

38

NSCalendar имеют методы для всех трех случаев

func isDateInYesterday(_ date: NSDate) -> Bool 
func isDateInToday(_ date: NSDate) -> Bool 
func isDateInTomorrow(_ date: NSDate) -> Bool 

Для расчета дней раньше, чем вчера используют

func components(_ unitFlags: NSCalendarUnit, 
     fromDate startingDate: NSDate, 
      toDate resultDate: NSDate, 
       options opts: NSCalendarOptions) -> NSDateComponents 

проход .Day в unitFlags и получить day p из результата.

Edit:

Это функция, которая учитывает также is in для более ранних и более поздних дат, лишив часть времени.

func dayDifferenceFromDate(timestamp : Int) -> String 
{ 
    let calendar = NSCalendar.currentCalendar() 
    let date = NSDate(timeIntervalSince1970: Double(timestamp)) 
    if calendar.isDateInYesterday(date) { return "Yesterday" } 
    else if calendar.isDateInToday(date) { return "Today" } 
    else if calendar.isDateInTomorrow(date) { return "Tomorrow" } 
    else { 
    let startOfNow = calendar.startOfDayForDate(NSDate()) 
    let startOfTimeStamp = calendar.startOfDayForDate(date) 
    let components = calendar.components(.Day, fromDate: startOfNow, toDate: startOfTimeStamp, options: []) 
    let day = components.day 
    if day < 1 { return "\(abs(day)) days ago" } 
    else { return "In \(day) days" } 
    } 
} 

Обновление для Swift 3:

func dayDifference(from interval : TimeInterval) -> String 
{ 
    let calendar = NSCalendar.current 
    let date = Date(timeIntervalSince1970: interval) 
    if calendar.isDateInYesterday(date) { return "Yesterday" } 
    else if calendar.isDateInToday(date) { return "Today" } 
    else if calendar.isDateInTomorrow(date) { return "Tomorrow" } 
    else { 
     let startOfNow = calendar.startOfDay(for: Date()) 
     let startOfTimeStamp = calendar.startOfDay(for: date) 
     let components = calendar.dateComponents([.day], from: startOfNow, to: startOfTimeStamp) 
     let day = components.day! 
     if day < 1 { return "\(abs(day)) days ago" } 
     else { return "In \(day) days" } 
    } 
} 
+0

Спасибо! Верхняя часть выглядит идеально. С нижней частью это может быть 10 утра здесь, но отметка времени может быть завтра 9 утра, что даст другой результат, если завтра 11 утра. Или я неправильно понял, как это работает? – Ben

+0

Отличный материал, спасибо еще раз. Единственное изменение, которое я сделал, это линия дней назад, добавив 'abs' для удаления отрицания, то есть' return '\ (abs (day)) дней назад »' – Ben

+0

Конечно, спасибо :-) – vadian

5

У NSCalender есть новые методы, которые вы можете использовать напрямую.

NSCalendar.currentCalendar().isDateInTomorrow(NDSate())//Replace NSDate() with your date 
NSCalendar.currentCalendar().isDateInYesterday() 
NSCalendar.currentCalendar().isDateInTomorrow() 

Надеется, что это помогает

25

Swift 3.0:

NSCalendar.current.isDateInToday(yourDate) 
NSCalendar.current.isDateInYesterday(yourDate) 
NSCalendar.current.isDateInTomorrow(yourDate) 

Дополнительно:

NSCalendar.current.isDateInWeekend(yourDate) 

Обратите внимание, что для некоторых стран выходные могут отличаться от субботы и воскресенья, это зависит от календаря.

Вы также можете использовать autoupdatingCurrent вместо current, который будет отслеживать обновления пользователей. Вы можете использовать его таким же образом:

NSCalendar.autoupdatingCurrent.isDateInToday(yourDate) 

Update:

Вы можете также использовать Calendar, который является типом псевдоним NSCalendar.

7

Swift 4 обновление:

let calendar = Calendar.current 
    let date = Date() 

    calendar.isDateInYesterday(date) 
    calendar.isDateInToday(date) 
    calendar.isDateInTomorrow(date) 
Смежные вопросы