如何在Swift中减去两个NSDates?

时间:2016-02-29 20:39:37

标签: swift nsdate

我已经搜索了如何做到这一点,但答案对我不起作用,所以我再问一遍。 在我的应用程序中,用户添加任务和截止日期。如果截止日期已从当前日期过去,我想将名为“pendenciaLbl”(在单元格类中)的标签更改为“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日。

2 个答案:

答案 0 :(得分:2)

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

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

编辑:

我发现您的日期存储为" 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的方法,以便您可以使用标准不等式表达式直接比较日期,以查看哪个更大/更小:

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个日期是否完全匹配。我不知道为什么他们没有采取下一个明显的步骤,并且开始支持可比协议#34;开箱即用。&#34;似乎很荒谬。

答案 1 :(得分:1)

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