如何在 Swift 中减去两个 NSDates?

How to subtract two NSDates in Swift?

我已经搜索过如何做到这一点,但答案对我不起作用,所以我再次询问。 在我的应用程序中,用户添加了任务和截止日期。如果截止日期已从当前日期过去,我想将名为 "pendenciaLbl" 的标签(位于单元格 class 中)更改为 "Late",并将截止日期标签更改为 "Passed due date" 这样用户就知道截止日期已经过去了。 我使用的代码是这样的:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCellWithIdentifier("AtivCell") as? AtivCell {


        cell.configureCell(materias[indexPath.row], date: dates[indexPath.row], descricao: descricoes[indexPath.row], pendencia: pendencia[indexPath.row], categoria: categorias[indexPath.row])

        let calendar = NSCalendar.currentCalendar()
        let dateFormatter = NSDateFormatter()
        let currentDate = NSDate()
        let flags = NSCalendarUnit.Day
        if let transformedDate = dateFormatter.dateFromString(dates[indexPath.row]) {
        let components = calendar.components(flags, fromDate: transformedDate, toDate: currentDate, options: [])

            if components.day >= 1 {
                dates[indexPath.row] = "Passes due date"
                cell.pendenciaLbl.text = "Late"
                cell.pendenciaLbl.textColor = UIColor.blueColor()
            }
        }
        return cell
    } else {
        return AtivCell()
    }
}

问题是这段代码不起作用,我不知道为什么。我已经通过添加一个已经过去的日期(比如昨天)进行了测试,但标签仍然相同。如果有任何帮助,我将不胜感激。

重要提示:日期 [indexPath] 的格式为 "MMM, dd, yyyy",例如 2016 年 2 月 29 日。

NSDate 实际上只是一个 Double,包含自 Cocoa "epoch date" 以来的秒数,以及方法。您可以使用 NSDate 实例方法 timeIntervalSinceReferenceDate 来比较 2 个日期:

let now = NSDate()
let later = NSDate(timeIntervalSinceNow: 300)
if later.timeIntervalSinceReferenceDate > now.timeIntervalSinceReferenceDate
{
  print( "later is greater than now")
}

创建符合 Equatable 和 Comparable 协议的 NSDate class 扩展也很容易。如果这样做,您可以使用 ==、>、< 等直接比较日期。

编辑:

我看到您的日期以 "MMM, dd, yyyy" 格式存储为字符串。在这种情况下,您需要使用该格式字符串设置日期格式化程序,以便它能够在比较它们之前将它们转换为日期。

完整示例可能如下所示:

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM, dd, yyyyy"
if let someDate = dateFormatter.dateFromString("Mar, 02, 2016")
{
  let now = NSDate()

  if someDate.timeIntervalSinceReferenceDate > now.timeIntervalSinceReferenceDate
  {
    print("someDate is greater than now")
  }
  else
  {
    print("now is >= someDate")
  }
}
else
{
  print("date string \"\(dateString)\" is invalid")
}

编辑#2:

这是扩展 NSDate 的方法,这样您就可以直接使用标准不等式表达式比较日期,看看哪个是 larger/smaller:

extension NSDate: Comparable {}

//Define the global operators for the
//Comparable protocol for comparing NSDates

public func <(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 < rhs.timeIntervalSince1970
}
//-------------------------------------------------------------

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM, dd, yyyyy"

//The "if let" optional binding will only execute the code if the let 
//statement returns a non-nil value
if let someDate = dateFormatter.dateFromString("Jan, 02, 2016")
{
  let now = NSDate()

  if someDate > now
  {
    print("later is greater than now")
  }
  else
  {
    print("now is >= someDate")
  }
}
else
{
  print("date string \"\(dateString)\" is invalid")
}

看起来 Swift 2.0 将 Equatable 协议添加到 NSDate 的定义中,因此您可以使用 == 查看 2 个日期是否完全匹配。我不知道他们为什么不采取下一个明显的步骤并添加对 Comparable 协议的支持 "out of the box." 不这样做似乎很荒谬。

import Foundation

let dateFormatter = NSDateFormatter()

let str = "February, 29, 2016"

let date = dateFormatter.dateFromString(str) // nil !!!!!

// you HAVE TO SET .dateFormat first!!
dateFormatter.dateFormat = "MMM, dd, yyyy"
let date2 = dateFormatter.dateFromString(str)

您没有设置 dateFormatter.dateFormat,所以您的日期始终为 nil