Search code examples
iosnsdatensdateformatterutc

Converting ISO8601 Date Format to local time (iOS)


So there is a section on web application that users can enter events into and the web service sends those events to the mobile app in the following format:

"yyyy-MM-dd'T'HH:mm:ssZZZZZ"

I'm having issues trying to convert the string into a date so I can get just the time from the event (formatted in the correct timezone as well), So for example here's one that comes over "2015-03-20T20:00:00-07:00", which when I pull the time should be 1PM Pacific Time. But instead I either get 8PM or 3AM (depending on whether I add UTC abbreviation to the date formatter).

Here's what I have so far, I know I'm missing something here & maybe there's another date formatter that needs to be used but so far I can't figure out where I'm going wrong.

NSString *datePattern = @"yyyy-MM-dd'T'HH:mm:ssZZZZZ";
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:datePattern];
NSString *sString = [valueDict valueForKey:@"start_date"];
NSDate *startDate = [dateFormatter dateFromString:sString];
NSDateFormatter *timeFormatter = [NSDateFormatter new];
[timeFormatter setDateFormat:@"hh:mm a"];
[timeFormatter setLocale:[NSLocale systemLocale]];
NSString *timeString = [timeFormatter stringFromDate:startDate];

Solution

  • 2015-03-20T20:00:00-07:00 is 8pm Pacific Daylight Time.

    If you're representing 1pm PDT, that's either

    • 2015-03-20T13:00:00-07:00

    or represent that in "Zulu" (i.e. GMT/UTC)

    • 2015-03-20T20:00:00Z

    When working with a web service, the latter is the common convention for ISO 8601 dates. Then, when you present it to the user, you present it to them in their local timezone (using a NSDateFormatter with its default timeZone setting.


    Note, when using NSDateFormatter to prepare ISO 8601 dates, you will want to ensure that you specify a locale of en_US_POSIX as outlined in Technical Q&A QA1480. When designing app for US audience this isn't critical, but it's best practice in case the user is not using a gregorian calendar on their device.