Reputation: 107
So I am trying to convert some times I receive in UTC/GMT to the local time zone using the following code:
let gmtFormatter: NSDateFormatter = NSDateFormatter()
gmtFormatter.timeZone = NSTimeZone(name: "GMT")
gmtFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let gmtDate: NSDate = gmtFormatter.dateFromString(dateString)!
print("GMT \(gmtDate)")
let localFormatter: NSDateFormatter = NSDateFormatter()
localFormatter.timeZone = NSTimeZone.localTimeZone()
localFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let localDate: NSDate = localFormatter.dateFromString(gmtFormatter.stringFromDate(gmtDate))!
print("Local \(localDate)")
However, I find that the conversion is working in revers. PST is UTC-8 and the outputs are 8 hours ahead instead of 8 hours behind. So I tested with a London Time Zone (CET) which is UTC+1 and should be 1 hour ahead of GMT. The results was a time that was 1 hour behind.
This was the string I am testing with: "2016-02-24 00:05:54"
For PST this should convert to 2016-02-23 04:05:54, but instead converts to 2016-02-24 08:05:54 (notice the way it should be is on the 23rd and not the 24th)
For CET this should convert to 2016-02-24 01:05:54, but instead converts to 2016-02-23 23:05:54 (notice the way it should be is on the 24th and not the 23rd)
Am I missing something glaring?
Upvotes: 1
Views: 1103
Reputation: 534925
The problem is that in the second part of your code...
let localDate: NSDate =
localFormatter.dateFromString(gmtFormatter.stringFromDate(gmtDate))!
... you're doing the opposite of what you want. An NSDate is absolute. Its string representation is what is volatile, as it were. So having turned a string into a date with your first formatter, what you now want to do is turn that date into a string with your second formatter.
For example, I'm in California. Now, watch this:
let dateString = "2016-02-24 10:09:08"
let gmtFormatter: NSDateFormatter = NSDateFormatter()
gmtFormatter.timeZone = NSTimeZone(name: "GMT")
gmtFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let gmtDate: NSDate = gmtFormatter.dateFromString(dateString)!
print("GMT \(gmtDate)")
let localFormatter: NSDateFormatter = NSDateFormatter()
localFormatter.timeZone = NSTimeZone.localTimeZone()
localFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let localDateString = localFormatter.stringFromDate(gmtDate) // <-- !!!
print("Local \(localDateString)")
Result:
GMT 2016-02-24 10:09:08 +0000
Local 2016-02-24 02:09:08
That's correct. When it's 10 AM in London, it's 2 AM here.
To put it another way, if you think what you're doing is converting a date from one time zone to another, you have not understood what a date is. It is a date-time and a time zone. There is nothing to convert: it is completely determined, and it is correct no matter where you are, because it says what time zone it is.
Perhaps it would be a bit clearer to you if I changed the next-to-last line format to this:
localFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
The final output is then:
Local 2016-02-24 02:09:08 -0800
which is obviously correct.
Upvotes: 5