5

I need to convert a date string retrieved from a server, to local NSDate, the string looks like:

"Fri, 30 Nov 2012 00:35:18 GMT"

But now it is Friday, 30th Nov, 11:36 AM, so how do I convert the string to a meaningful local NSDate?

I found:

iPhone: NSDate convert GMT to local time

But looks like it does the opposite.

Community
  • 1
  • 1
hzxu
  • 5,753
  • 11
  • 60
  • 95

2 Answers2

16

Note that NSDate's always store the date, internally, in GMT. You then use a date formatter to create a string in your local time zone. In this case, you are starting with a string so need to use the date formatter to create the date in the first place, and then use it again to create a string in your local time zone (which it defaults to when the timezone is not specified).

NSString *dateString           = @"Fri, 30 Nov 2012 00:35:18 GMT";

NSDateFormatter *dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat       = @"EEE, dd MM yyyy HH:mm:ss zzz";

NSDate *date                   = [dateFormatter dateFromString:dateString];
NSString *localDateString      = [dateFormatter stringFromDate:date];

NSLog(@"%@", localDateString);
// Results:  Thu, 29 11 2012 19:35:18 EST
lnafziger
  • 25,760
  • 8
  • 60
  • 101
  • Oops; I had the wrong zeds in my answer. +1. Though you should still set the locale explicitly — otherwise `NSDateFormatter` reserves the right to modify your exact formatting string. – Tommy Nov 30 '12 at 00:51
  • @Tommy: If I'm not mistaken, the locale defaults to your current locale. I just NSLog'd dateFormatter.locale.localeIdentifier (without setting it) and it gave me "en_US", which is my current locale. That's why I didn't set it, because he wanted it in his local timezone. – lnafziger Nov 30 '12 at 00:54
  • @lnafziger locale and timezone are to independent properties. Using the locale `en_US_POSIX` is important when working with fixed format date/time strings. Without it, it's possible the format will be changed behind your back based on things like the user's 24-hour setting (as one example). Setting the locale has no effect on the format's time zone. See the QA1480 that @Tommy referenced in his answer. – rmaddy Nov 30 '12 at 01:12
  • @rmaddy: I don't understand the point that you are trying to make. The locale on a date formatter that I create defaults to `en_US`. If I am going to display this string to a user, I **want** it to respect the users 24-hour setting, as well as anything else that is specified. When I am converting **from** a date format (as in this example) the date format specifies the format to expect and it shouldn't matter what the user has specified in his preferences.... Am I misunderstanding something here?? – lnafziger Nov 30 '12 at 01:37
  • @lnafziger if you need an exact format you need to set the en_US_POSIX locale. When creating a user format that adapts to various settings then you leave the default locale. – rmaddy Nov 30 '12 at 03:08
  • @rmaddy: Okay, that's what I thought and why I didn't set a locale here. You guys were just trying your best to confuse me, lol! – lnafziger Nov 30 '12 at 03:38
  • Thanks a lot! The question which has been linked in the question should be corrected. It does local to GMT as opposed to GMT to local. – Bilbo Baggins May 20 '13 at 13:27
1

Just use NSDateFormatter with the formatting string eee, dd MMM yyyy HH:mm:ss zzz. The Zs at the end cause it to read the time zone from the string.

So, given QA1480, sample code:

NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setLocale:usLocale];
[formatter setDateFormat:@"eee, dd MMM yyyy HH:mm:ss zzz"];
_createdAt = [formatter dateFromString:dateString];
Tommy
  • 99,986
  • 12
  • 185
  • 204
  • In the link in my question, he used `NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; [dateFormatter setTimeZone:gmt];` why do you not need this? – hzxu Nov 30 '12 at 00:43
  • You don't need that because your string specifies GMT in it and the `zzz` component of the date format you've set will tell `NSDateFormatter` to use what your string specifies rather than whatever it considers the norm to be. – Tommy Nov 30 '12 at 00:49