Nishant Chandwani
Nishant Chandwani

Reputation: 445

Swift 2.1 xcode 7 fatal error: when i change string to date but is working in swift 2.0

I am simply string convert in nsdate but its always return me error "fatal error: unexpectedly found nil while unwrapping an Optional value" Line number 6 let startDate:NSDate = dateFormatter.dateFromString(start)!

Here is my code. Please suggest a solution, because this code working in swift 2.0 version but is't crash on swift 2.1

func doSomething(getdate:String)  -> String   {
    let start = getdate
    print("start==\(start)")
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-­MM-­dd HH:mm:ss"
    let startDate:NSDate = dateFormatter.dateFromString(start)!
    let date:String? = (self.timeAgoSinceDate(startDate, numericDates: Bool()))
    return date!
}

when I print a start variable is look like this start==2015-09-15 06:35:53

Upvotes: 0

Views: 451

Answers (2)

user3441734
user3441734

Reputation: 17582

import Foundation

let str = "2015-09-15 06:35:53"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
guard let startDate = dateFormatter.dateFromString(str) else {
    exit(-1)
}
print(startDate)        // 2015-09-15 04:35:53 +0000
dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
guard let startDateUTC = dateFormatter.dateFromString(str) else {
    exit(-1)
}
print(startDateUTC)     // 2015-09-15 06:35:53 +0000

Please, follow dfri instructions about binding the result of dateFromString()

If there in no specification about timezone in your string, use "UTC" as timeZone. Then you have some 'reference' date in very known format and you can compare it or make something else ... If you know the timeZone of the source of your string, you can use that timeZone directly.

dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")

will NOT change the timeZone settings, so check the resulting NSDate before use!

For your reference I recommend you this reading

Upvotes: 0

dfrib
dfrib

Reputation: 73236

The reasons for your error is the forced unwrapping of a nil return from method .dateFromString() method (class method for NSDateFormatter). You code is, in it's current form, unsafe, and just happened to pass without runtime errors in your previous runs.

From the language reference for class NSDateFormatter method .dateFromString(), we have

...

Returns a date representation of a given string interpreted using the receiver’s current settings. A date representation of string interpreted using the receiver’s current settings. If dateFromString: can not parse the string, returns nil.

To begin with, we should make sure the behaviour of your code is well-defined by avoiding forced unwrapping of optional, by using if-let clauses (or guard-let, or nil coalescing operator ??) instead of forced unwrapping (!).

Now, I don't have the context of your code, but consider fixing the forced unwrapping in you function to change it into a form like

func doSomething(getdate:String)  -> String   {
    let start = getdate
    print("start==\(start)")
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yyyy-­MM-­dd HH:mm:ss"
    var date : String?
    if let startDate = dateFormatter.dateFromString(start) {
        date = (self.timeAgoSinceDate(startDate, numericDates: Bool()))
    }

    return date ?? ""
}

With this out of the way, we can proceed to examine why .dateFromString(start) fails to parse the string.

Based on the following threads

possibly, you need to specify the .locale property of the dateFormatter. Try to add one of the two following line

dateFormatter.locale = NSLocale(localeIdentifier: "us")
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")

right after you've defined the dateFormatter.dateFormat.


Note, however, that the most probable cause as to why .dateFromString(start) fails to parse the string, and hence returns nil, is that your string start simply does not comply to dateFormat. It does look, given your printed output of start, that it does, but please have an extra look to see if this is really always the case, for all possible calls to your function. Neither .locale or .timeZone should affect whether .dateFromString(...) can parse its argument or not. Only .dateFormat controls this success or non-success of string parsing.

Upvotes: 1

Related Questions