NSDateFormatter return wrong date + Swift

Solution 1:

I had the same problem and i this worked for me

You need to set the time zone

formatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")

Solution 2:

When you convert from string to NSDate, if you do not set the timezone to the formatter, you will get the NSDate of a date in your local time zone. I suppose that your time zone is GMT+3 .

Then, when you show the value of 'date' (using println, NSLog but not NSDateFormatter), without setting the time zone, you will get GMT+0 time. That why you got 3h later.

Depend on how to use NSDateFormatter, you will have the date string as you want. In your case, It returns what you want, doesn't it?

Remember that NSDate presents a moment of time.

let dateString = "2016-04-02"
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
println("dateString: \(dateString)")

formatter.locale =  NSLocale(localeIdentifier: "en_US_POSIX")
let date = formatter.dateFromString(dateString) //without specify timezone, your dateString "2016-04-02" is your local time (GMT-3),  
//means it's 2016-04-02 00:00:000 at GMT+0. That is the value that NSDate holds.

println("date: \(date)") //that why it show 2016-04-01 21:00:000, but not 2016-04-02 00:00:000

formatter.dateFormat = "yyyy-MM-dd"
let formattedDateString = formatter.stringFromDate(date!)
println("formattedDateString: \(formattedDateString)")

Solution 3:

Your date is perfectly good. :-) No pun intended.

I will elaborate more on what @HoaParis has answered.

First of all NSDate represents a moment in time. It is not a date time value at the given place. So NSDate representing midnight in Greenwich will be 5:30 in morning in India.

Now coming to your question. When you give a date format with out time the formatter will assume it to be mid night. Also if there is not timezone mentioned it will take the current time zone.

So '2016-04-02' represents '2016-04-02, 00:00:00' at your time zone. Your timezone is GMT+3 that means when it is midnight at your place it is still 21:00:00 hours of previous day at Greenwich i.e. UK.

As we discussed NSDate is a moment in time to the same NSDate object represents these two seemingly different times but in reality they are the same time moment.

When you print the date by default it will print the date with respect to GMT and not your time zone i.e 2016-04-01, 21:00:00. The formatter will take into account your time zone and make it '2016-04-02'

Solution 4:

let dateFormatter = DateFormatter()
  //Your current Date Format 
  dateFormatter.dateFormat = "yyyy-MM-dd"
  dateFormatter.locale = Locale(identifier: "en_US_POSIX")
  dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
  let finaldate = dateFormatter.date(from:"Your String")

  //Your changing Date Format 
  dateFormatter.dateFormat = "MMM-dd"
  let second = dateFormatter.string(from: finaldate!)