Parsing JSON dates on IPhone

datetime, iphone, json, objective-c

Solution

As a .NET programmer learning Objective-C I had the same problem when I tried to consume a .Net WebService.

At first I thought I would be able to use the NSDateFormatter... I found a really good reference for it's symbols here, but I quickly realized that I needed to convert the number from milliseconds to seconds.

I wrote the code to do it... I'm still learning Obj-C but I dont think It should've been this hard...

- (NSDate *) getJSONDate{
    NSString* header = @"/Date(";
    uint headerLength = [header length];

    NSString*  timestampString;

    NSScanner* scanner = [[NSScanner alloc] initWithString:self];
    [scanner setScanLocation:headerLength];
    [scanner scanUpToString:@")" intoString:&timestampString];

    NSCharacterSet* timezoneDelimiter = [NSCharacterSet characterSetWithCharactersInString:@"+-"];
    NSRange rangeOfTimezoneSymbol = [timestampString rangeOfCharacterFromSet:timezoneDelimiter];

    [scanner dealloc];

    if (rangeOfTimezoneSymbol.length!=0) {
        scanner = [[NSScanner alloc] initWithString:timestampString];

        NSRange rangeOfFirstNumber;
        rangeOfFirstNumber.location = 0;
        rangeOfFirstNumber.length = rangeOfTimezoneSymbol.location;

        NSRange rangeOfSecondNumber;
        rangeOfSecondNumber.location = rangeOfTimezoneSymbol.location + 1;
        rangeOfSecondNumber.length = [timestampString length] - rangeOfSecondNumber.location;

        NSString* firstNumberString = [timestampString substringWithRange:rangeOfFirstNumber];
        NSString* secondNumberString = [timestampString substringWithRange:rangeOfSecondNumber];

        unsigned long long firstNumber = [firstNumberString longLongValue];
        uint secondNumber = [secondNumberString intValue];

         NSTimeInterval interval = firstNumber/1000;

        return [NSDate dateWithTimeIntervalSince1970:interval];
    }

    unsigned long long firstNumber = [timestampString longLongValue];
    NSTimeInterval interval = firstNumber/1000;

    return [NSDate dateWithTimeIntervalSince1970:interval];
}

Hopefully someone can provide a better Obj-C solution. If not I may keep this or look for a way to change the serialization format in .NET

EDIT:

About that JSON DateTime format... If you have any control on the service it would probably be best to convert the date to a string in your DataContract objects.

Formatting to RFC1123 seems like a good idea to me right now. As I can probably pick it up easily using a NSDateFormatter.

Quote from Rick Strahl

There's no JavaScript date literal and Microsoft engineered a custom date format that is essentially a marked up string. The format is a string that's encoded and contains the standard new Date(milliseconds since 1970) value.

Problem

Forgive me as I'm new to Objective C. I am getting back dates from a .NET webservice in the /Date(xxxxxxxxxxxxx-xxxx)/ format. I'm looking for some direction on how to best parse this into an NSDate object. I've tried using dateWithTimeIntervalSince1970 on it but it comes back with a date in the year 1969 for a date I know is in 2006. Looking for some direction on the proper way to handle JSON dates. Thanks in advance!

Original source