8

I am trying to set the date format for something like "2011-04-21 03:31:37.310396". I think I'm not getting the fractional seconds right. I'm looking at http://unicode.org/reports/tr35/tr35-10.html#Date_Format_Patterns for guidelines on how to specify it and I think my issue is in the format itself.

NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ssSSSSSS";     
NSDate* serverDate = [dateFormatter dateFromString:stringFormOfDate];    

Help?

Joey
  • 7,537
  • 12
  • 52
  • 104

2 Answers2

23

try

NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSSSSS";     
NSDate* serverDate = [dateFormatter dateFromString:@"2011-04-21 03:31:37.310396"]; 

NSLog(@"%@", serverDate);

I guess you probably forgot the dot

superandrew
  • 1,741
  • 19
  • 35
  • 8
    While this appears to work note that `NSDateFormatter` output is limited to mili-seconds. Any "S" format characters past 3 will produce "0". The same applies to creating a date. The time interval for the example produces: "325063897.310000". So this may not actually answer the question since the 396 micro-seconds are lost. (tested on OSX, not iPhone) – zaph Jul 15 '13 at 19:53
8

As per Zaph's comment in the other answer: the maximum number of S is 3. Any more just produce zeros.

E.g.

dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSSSSS"; // Last 3 'S' ignored.  

Then @"2011-04-21 03:31:37.311396" will produce 2011-04-21 03:31:37.311000

To maintain full microsecond precision try this magic:

-(NSDate *)_dateFromUtcString:(NSString *)utcString{
    if(!utcString){
        return nil;
    }
    static NSDateFormatter *df = nil;
    if (df == nil) {
        df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        [df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    }

    NSArray* parts = [utcString componentsSeparatedByString:@"."];
    NSDate *utcDate = [df dateFromString:parts[0]];
    if(parts.count > 1){
        double microseconds = [parts[1] doubleValue];
        utcDate = [utcDate dateByAddingTimeInterval:microseconds / 1000000];
    }
    return utcDate;
}

Now an NSString "2011-04-21 03:31:37.310396" will parse fully to an NSDate 2011-04-21 03:31:37.310396

malhal
  • 26,330
  • 7
  • 115
  • 133