如何重写我的swift代码,以便它也考虑计算未来两个日期之间的差异?

问题描述:

我有一个类函数,需要一个NSDate对象,并返回一个人类可读的字符串告诉用户多久以前这个日期出现。它看起来像这样:如何重写我的swift代码,以便它也考虑计算未来两个日期之间的差异?

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

} 

我想改写这个函数(或者 - 如果它更容易 - 创建另一个)也需要一个NSDate作为参数,但这次输入日期是在未来,所以输出应该是这样的:

in couple minutesin couple hoursin xx seconds

你能帮助我吗?

+1

看起来这样的逻辑与你已经写的相似。你卡在哪里? – jtbandes

+0

不是直接回答你的问题,但你有没有考虑过使用'NSDateComponentsFormatter'?它大致与您的代码具有相同的功能。 –

远非如此,因为您对编写此代码特别感兴趣,所以试着阻止您,如果您这样做。但是,如果您只是想要字符串结果并编写代码作为达到此目的的手段 - 那么您可能想要让自己更容易并使用NSDateComponentsFormatter。东西非常接近你的描述,对于过去和将来的日期作品:

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 
} 

那么你可以这样做:

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" 

更改为格式调整的结果allowedUnits值。