heisenberg heisenberg - 1 month ago 14
Swift Question

Problems with NSDateFormatter, returns nil when using .dateFromString

I'm having problems with NSDateFormatter. I implemented a date picker where you can choose two dates to calculate the difference between these two dates and return the difference in days. The two dates are in the following format (.MediumStyle):

var firstDate = "Nov 3, 2016"
var lastDate = "Nov 9, 2016"


However when it gets to the part in the function called
calculateDifference()
where these two values are being converted to an type of
NSDate
, the method returns
nil
.

My code is as follows:

@IBOutlet weak var startDateOutput: UILabel! // shows start date user picked
@IBOutlet weak var endDateOutput: UILabel! // shows end date user picked
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var answerFieldTimeDifference: UILabel! // Output Field

var firstDate = ""
var lastDate = ""

@IBAction func startButton(sender: AnyObject) // Button to set firstDate
{

firstDate = NSDateFormatter.localizedStringFromDate(datePicker.date, dateStyle: NSDateFormatterStyle.MediumStyle, timeStyle: NSDateFormatterStyle.NoStyle)
startDateOutput.text = firstDate
calculateDifference()
}

@IBAction func expirationButton(sender: AnyObject) // Button to set lastDate
{
lastDate = NSDateFormatter.localizedStringFromDate(datePicker.date, dateStyle: NSDateFormatterStyle.MediumStyle, timeStyle: NSDateFormatterStyle.NoStyle)
endDateOutput.text = lastDate
calculateDifference()
}

func calculateDifference()
{
if !firstDate.isEmpty && !lastDate.isEmpty
{
let dateFormatter = NSDateFormatter()
let firstDateAsNSDate = dateFormatter.dateFromString(firstDate) //returns nil
let lastDateAsNSDate = dateFormatter.dateFromString(lastDate) //returns nil

let dateComponentsFormatter = NSDateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [NSCalendarUnit.Day]

var calculatedDifference = dateComponentsFormatter.stringFromDate(firstDateAsNSDate!, toDate: lastDateAsNSDate!)

answerFieldTimeDifference.text = calculatedDifference
}
}


I don't know if I'am misunderstanding it. It's my first time ever working with NSDate etc. I would really appreciate any help and I'd be thankful if you could explain it in plain words.

Answer

The reason you get nil in calculateDifference is because you never set a date format or style to the date formatter.

But there is no reason at all to use strings and date formats. Keep everything as NSDate and avoid all of the needless extra work.

@IBOutlet weak var startDateOutput: UILabel! // shows start date user picked
@IBOutlet weak var endDateOutput: UILabel! // shows end date user picked
@IBOutlet weak var datePicker: UIDatePicker!
@IBOutlet weak var answerFieldTimeDifference: UILabel! // Output Field

var firstDate : NSDate?
var lastDate : NSDate?

@IBAction func startButton(sender: AnyObject) // Button to set firstDate
{
    firstDate = datePicker.date
    let dateStr = NSDateFormatter.localizedStringFromDate(firstDate, dateStyle: NSDateFormatterStyle.MediumStyle, timeStyle: NSDateFormatterStyle.NoStyle)
    startDateOutput.text = dateStr
    calculateDifference()
}

@IBAction func expirationButton(sender: AnyObject) // Button to set lastDate
{
    lastDate = datePicker.date
    let dateStr = NSDateFormatter.localizedStringFromDate(lastDate, dateStyle: NSDateFormatterStyle.MediumStyle, timeStyle: NSDateFormatterStyle.NoStyle)
    endDateOutput.text = dateStr
    calculateDifference()
}

func calculateDifference()
{
    if let firstDate = firstDate, let lastDate = lastDate
    {
        let dateComponentsFormatter = NSDateComponentsFormatter()
        dateComponentsFormatter.allowedUnits = [NSCalendarUnit.Day]

        var calculatedDifference = dateComponentsFormatter.stringFromDate(firstDate, toDate: lastDate)

        answerFieldTimeDifference.text = calculatedDifference
    }
}