17

Code :

let dateString = "2016-04-02"
    var formatter: NSDateFormatter = NSDateFormatter()
    formatter.timeZone = NSTimeZone(abbreviation: "GMT +3:00")
    formatter.dateFormat = "yyyy-MM-dd"
    println("dateString: \(dateString)")
    formatter.locale =  NSLocale(localeIdentifier: "en_US_POSIX")
    let date = formatter.dateFromString(dateString)
    println("date: \(date)")

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

Output :

dateString: 2016-04-02
date: Optional(2016-04-01 21:00:00 +0000)
formattedDateString: 2016-04-02
2016-04-01 21:00:00 +0000

I am trying to convert a string to NSDate datatype but not getting correct value. I have tried many solutions but its not returning correct value. I need it in yyyy-MM-dd format (2016-04-02) same as my input "2016-04-02". If someone can help would be really apriciated. Thanks in advance

Sanjay Kumar
  • 415
  • 4
  • 9
  • 19
  • Sorry, we cannot understand your question. The output you list in the question seems to meet your requirements. Can you clarify, please? – emrys57 Apr 02 '15 at 08:19
  • No.. 1 day is missing.. my input is 2016-04-02 but output is 2016-04-01 – Sanjay Kumar Apr 02 '15 at 11:35
  • possible duplicate of [returns a date an hour in the future](http://stackoverflow.com/questions/4976530/returns-a-date-an-hour-in-the-future) – Matthias Bauch Apr 02 '15 at 15:10
  • I am using webservice with soap so i changed datatype to string in webservice so no need to bump my head in wall. Thanks alot for helping me.. – Sanjay Kumar Apr 03 '15 at 13:01

4 Answers4

18

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

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)")
Duyen-Hoa
  • 15,384
  • 5
  • 35
  • 44
  • I used formatter.timeZone = NSTimeZone(abbreviation: "GMT+3:00"); formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") still getting 2016-04-01 21:00:00 +0000 – Sanjay Kumar Apr 02 '15 at 11:06
  • Actually its not returning the correct date.. input : 2016-04-02 - output : 2016-04-01 21:00:00 +0000 means one day is missing here – Sanjay Kumar Apr 02 '15 at 11:10
  • Because your timezone with GMT+3 is your time zone. As I said, NSDateFormatter take our local time zone by default. So it will give you the same result as without specify anything. Second thing, there is 3h of 'missing' but not a day. – Duyen-Hoa Apr 02 '15 at 12:40
  • when you convert using GMT+3 with your date string, it means, that time in GMT+3 is 2016-04-02 00:00:000. So at the same moment, the time in a time zone GMT+0 is 3 hour later than you, mean 2016-04-01 21:00:00 +0000. Hope that its more clear. – Duyen-Hoa Apr 02 '15 at 12:42
6

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'

Abdullah
  • 7,143
  • 6
  • 25
  • 41
5
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!)
MK_iOS
  • 388
  • 5
  • 13