2016-04-17 12 views
0

Ich habe eine Klassenfunktion, die ein NSDate Objekt annimmt und eine vom Menschen lesbare Zeichenfolge zurückgibt, die dem Benutzer mitteilt, wie lange dieses Datum schon erschienen ist. Es sieht wie folgt aus:Wie kann ich meinen Swift-Code so umschreiben, dass er auch die Berechnung von Differenzen zwischen zwei Daten berücksichtigt, wenn einer in der Zukunft liegt?

class func timeAgoSinceDate(date:NSDate, numericDates:Bool) -> String { 
    let calendar = NSCalendar.currentCalendar() 
    let now = NSDate() 
    let earliest = now.earlierDate(date) 
    let latest = (earliest == now) ? date : now 
    let components:NSDateComponents = calendar.components([NSCalendarUnit.Minute , NSCalendarUnit.Hour , NSCalendarUnit.Day , NSCalendarUnit.WeekOfYear , NSCalendarUnit.Month , NSCalendarUnit.Year , NSCalendarUnit.Second], fromDate: earliest, toDate: latest, options: NSCalendarOptions()) 

    if (components.year >= 2) { 
     return "\(components.year) years ago" 
    } else if (components.year >= 1){ 
     if (numericDates){ 
      return "1 year ago" 
     } else { 
      return "last year" 
     } 
    } else if (components.month >= 2) { 
     return "\(components.month) months ago" 
    } else if (components.month >= 1){ 
     if (numericDates){ 
      return "1 month ago" 
     } else { 
      return "last month" 
     } 
    } else if (components.weekOfYear >= 2) { 
     return "\(components.weekOfYear) weeks ago" 
    } else if (components.weekOfYear >= 1){ 
     if (numericDates){ 
      return "1 week ago" 
     } else { 
      return "last week" 
     } 
    } else if (components.day >= 2) { 
     return "\(components.day) days ago" 
    } else if (components.day >= 1){ 
     if (numericDates){ 
      return "1 day ago" 
     } else { 
      return "yesterday" 
     } 
    } else if (components.hour >= 2) { 
     return "\(components.hour) hours ago" 
    } else if (components.hour >= 1){ 
     if (numericDates){ 
      return "1 hour ago" 
     } else { 
      return "an hour ago" 
     } 
    } else if (components.minute >= 2) { 
     return "\(components.minute) minutes ago" 
    } else if (components.minute >= 1){ 
     if (numericDates){ 
      return "1 minute ago" 
     } else { 
      return "a minute ago" 
     } 
    } else if (components.second >= 3) { 
     return "\(components.second) seconds ago" 
    } else { 
     return "just now" 
    } 

} 

Ich möchte diese Funktion neu zu schreiben (oder - wenn es einfacher ist - schaffen eine andere), die eine NSDate als Parameter auch, aber dieses Mal das Eingangsdatum in der Zukunft liegt, so sollte die Ausgabe wie folgt aussehen:

in couple minutes, in couple hours, in xx seconds usw.

können Sie mir helfen mit, dass?

+1

Es scheint, als ob die Logik dafür ähnlich wäre, was Sie bereits geschrieben haben. Wo steckst du fest? – jtbandes

+0

Nicht direkt eine Antwort auf Ihre Frage, aber haben Sie überlegt, 'NSDateComponentsFormatter' zu verwenden? Es hat ungefähr die gleiche Funktionalität wie Ihr Code. –

Antwort

0

Es ist weit weg von mir, Sie zu versuchen und zu stoppen, wenn Sie dies tun, weil Sie speziell daran interessiert sind, diesen Code zu schreiben. Aber wenn Sie nur die String-Ergebnisse wollen und den Code als Mittel zu diesem Zweck schreiben - dann möchten Sie wahrscheinlich die Dinge einfacher machen und NSDateComponentsFormatter verwenden. Etwas furchtbar nahe, was Sie beschreiben, die sowohl für vergangene und zukünftige Termine funktioniert:

func diffString(date:NSDate) -> String { 
    let now = NSDate() 

    let formatter = NSDateComponentsFormatter() 
    formatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Full 
    formatter.allowedUnits = [ .Day, .Hour, .Minute ] 

    let interval : NSTimeInterval = fabs(date.timeIntervalSinceDate(now)) 
    guard let intervalString = formatter.stringFromTimeInterval(interval) else { 
     return "" 
    } 

    let resultString : String 
    if now.timeIntervalSinceReferenceDate > date.timeIntervalSinceReferenceDate { 
     resultString = "\(intervalString) ago" 
    } else { 
     resultString = "in \(intervalString)" 
    } 
    return resultString 
} 

Anschließend können Sie tun:

let past = NSDate(timeIntervalSinceNow: -1000000) 
let future = NSDate(timeIntervalSinceNow: 1000000) 

diffString(past) // "11 days, 13 hours, 46 minutes ago" 
diffString(future) // "in 11 days, 13 hours, 46 minutes" 

Ändern Sie den allowedUnits Wert für den Formatierer die Ergebnisse anzupassen.