18

I have the following date:

2011-10-20T01:10:50Z

I would like it to be formatted to

"M/d/yy 'at' h:mma"

Here is my code:

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    //The Z at the end of your string represents Zulu which is UTC
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    [dateFormatter setDateFormat:@"yyyy-dd-MM'T'HH:mm:ss'Z'"];
    NSDate* newTime = [dateFormatter dateFromString:[message valueForKey:@"created_at"]];

    //Add the following line to display the time in the local time zone
    [dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
    [dateFormatter setDateFormat:@"M/d/yy 'at' h:mma"];
    NSString* finalTime = [dateFormatter stringFromDate:newTime];
    [dateFormatter release];
    NSLog(@"%@", finalTime);    

Unfortunately the finalTime is NULL here.

Sheehan Alam
  • 60,111
  • 124
  • 355
  • 556

3 Answers3

34

You have dd-MM backwards. You have 10 for dd and 20 MM. There is no month 20.

2011-10-20T01:10:50Z
@"yyyy-dd-MM'T'HH:mm:ss'Z'"

Because of that, the newTime was null and the finalTime was null.

Here's with the fix. This:

NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];

//The Z at the end of your string represents Zulu which is UTC
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];

NSDate* newTime = [dateFormatter dateFromString:@"2011-10-20T01:10:50Z"];
NSLog(@"original time: %@", newTime);

//Add the following line to display the time in the local time zone
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter setDateFormat:@"M/d/yy 'at' h:mma"];
NSString* finalTime = [dateFormatter stringFromDate:newTime];
NSLog(@"%@", finalTime);    

[dateFormatter release];

Outputs:

2011-10-19 22:05:15.107 Craplet[4231:707] original time: 2011-10-20 01:10:50 +0000
2011-10-19 22:05:15.116 Craplet[4231:707] 10/19/11 at 9:10PM
bryanmac
  • 38,941
  • 11
  • 91
  • 99
14

This technical note helped me resolve the same issue: https://developer.apple.com/library/ios/qa/qa1480/_index.html

In a nutshell, you need to set 3 things on NSDateFormatter:

  1. Locale
  2. TimeZone
  3. DateFormat

code sample:

NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:locale];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'"];

NSDate *date = [dateFormatter dateFromString:@"2014-10-23T01:10:50.000Z"];

I was using NSDateFormatter to successfully parse UTC strings to NSDate by only setting time zone and date format. When it suddenly stopped working I found this tech note and added setLocal: which resolved the issue for me.

Vojta
  • 810
  • 10
  • 16
100grams
  • 3,502
  • 3
  • 30
  • 27
5

Because Swift:

let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
let dateHopefully = dateFormatter.dateFromString("2016-07-29T17:15:02Z")

dateFormatter.timeZone = NSTimeZone.systemTimeZone()
dateFormatter.dateFormat = "M/d/yy 'at' h:mma"
let lastTime = dateFormatter.stringFromDate(dateHopefully!)

print("Here is the hopeful date \(dateHopefully) and here is the lastTime \(lastTime)")
Tunaki
  • 132,869
  • 46
  • 340
  • 423
MScottWaller
  • 3,321
  • 2
  • 24
  • 47