2016-09-06 19 views
13

Próbuję ustalić, jak zdecydować, czy dany znacznik czasu występuje dzisiaj, czy +1/-1 dni. Zasadniczo chciałbym zrobić coś takiego (pseudokod)Swift - sprawdź, czy znacznik czasu jest wczoraj, dziś, jutro lub X dni temu

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' 

Co najważniejsze jednak, że musi być w Swift i mam zmaga się z obiektami NSDate/NSCalendar. Zacząłem pracować na różnicę czasu tak:

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

Jednak porównując w ten sposób nie jest łatwe, ponieważ .Day różni się w zależności od pory dnia i datownik. W PHP używałbym mktime do stworzenia nowej daty, w oparciu o początek dnia (tj. mktime(0,0,0)), ale nie jestem pewien najprostszego sposobu, aby to zrobić w Swift.

Czy ktoś ma dobry pomysł, jak się do tego podejść? Być może rozszerzenie do NSDate lub coś podobnego byłoby najlepsze?

Odpowiedz

38

NSCalendar ma metody dla wszystkich trzech przypadkach

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

Aby obliczyć dni wcześniej niż wczoraj używają

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

przepustkę .Day do unitFlags i uzyskać jak day p roperty z wyniku.

Edit:

Jest to funkcja, która uważa również is in dla wcześniejszych i późniejszych terminach przez odpędzenie część czasu.

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" } 
    } 
} 

Aktualizacja 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

Dziękujemy! Górna część wygląda idealnie. Z dolną częścią może być tu 10 rano, ale znacznik czasu może być jutro o 9 rano, co dałoby inny wynik, gdyby było jutro o 11 rano. A może źle zrozumiałem, jak to działa? – Ben

+0

Świetne rzeczy, jeszcze raz dziękuję. Jedyną zmianą, jaką wprowadziłem, była linia dni, dodając "abs", aby usunąć negację, tj. 'Return" \ (abs (dzień)) dni temu "' – Ben

+0

Oczywiście, dzięki :-) – vadian

5

NSCalender ma nowe metody, z których można korzystać bezpośrednio.

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

Nadzieja to pomaga

25

Swift 3,0:

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

Dodatkowo:

NSCalendar.current.isDateInWeekend(yourDate) 

Należy pamiętać, że w niektórych krajach weekend może być inny niż sobota-niedziela, zależy to od kalendarza.

Można również użyć autoupdatingCurrent zamiast current kalendarza, który będzie śledzić aktualizacje użytkownika. Można go używać w taki sam sposób:

NSCalendar.autoupdatingCurrent.isDateInToday(yourDate) 

Aktualizacja:

można również użyć Calendar, który jest typu alias dla NSCalendar.

7

Swift 4 aktualizacja:

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

    calendar.isDateInYesterday(date) 
    calendar.isDateInToday(date) 
    calendar.isDateInTomorrow(date) 
Powiązane problemy