2012-01-24

JSON, .NET and NSDate

If you’re trying to access a JSON web service created using .NET from an iOS device, you’ve probably discovered that dates are produced in a less than useful format:

/Date(1233423345345)/

The rationale for the date format can be found here, but it’s basically a call to the JavaScript Date object constructor. The numeric value represents the number of milliseconds since 1970-01-01.

Below I’ve added a handy Objective-C function that will extract the value and return an NSDate object. Note that we’re losing accuracy by magnitudes as we translate from .NET DateTime objects (which measure time in ticks) to JavaScript Date objects (which measure time in milliseconds) and finally to iOS NSDate objects (which measure time in seconds).


/**
 * Converts a .NET JSON date in the format "/Date(x)/" to an NSDate object.
 * @param string The NSString to convert.
 * @return the NSDate object.
 */
(NSDate*)jsonStringToNSDate(NSString* string) {

    // Extract the numeric part of the date.  Dates should be in the format
    // "/Date(x)/", where x is a number.  This format is supplied automatically
    // by JSON serialisers in .NET.
    NSRange range = NSMakeRange(6, [string length] - 8);
    NSString* substring = [string substringWithRange:range];

    // Have to use a number formatter to extract the value from the string into
    // a long long as the longLongValue method of the string doesn't seem to
    // return anything useful - it is always grossly incorrect.
    NSNumberFormatter* formatter = [[NSNumberFormatter alloc] init];
    NSNumber* milliseconds = [formatter numberFromString:substring];

    [formatter release];

    // NSTimeInterval is specified in seconds.  The value we get back from the
    // web service is specified in milliseconds.  Both values are since 1st Jan
    // 1970 (epoch).
    NSTimeInterval seconds = [milliseconds longLongValue] / 1000;

    return [NSDate dateWithTimeIntervalSince1970:seconds];
}