objective-ciso8601nsformatter

Format Duration as ISO8601 Period with NSDateIntervalFormatter


I am trying to convert the duration between two dates to the format "'P'yyyy'Y'M'M'd'DT'H'H'm'M's.S'S'". An example of my expected output is: P0Y0M0DT0H0M0.002S (this is port of an Android project that uses DurationFormatUtils).

My test case:

NSDateIntervalFormatter *durationFormatter = [NSDateIntervalFormatter durationFormatter];
NSDate *date = [NSDate date];
NSDate *end = [date dateByAddingTimeInterval:25];
NSString *duration = [durationFormatter stringFromDate:date toDate:end];
XCTAssertTrue( [duration hasPrefix:@"P"], @"Actual String: %@", duration );

My formatter is defined as:

+ (NSDateIntervalFormatter*) durationFormatter {
    static NSDateIntervalFormatter *formatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSDateIntervalFormatter alloc] init];
        formatter.dateTemplate = @"'P'yyyy'Y'M'M'd'DT'H'H'm'M's.S'S'";
    });

    return formatter;
}

When I run this, duration is 3/5/2015, 16:46:20.3. If I set the locale on the formatter to nil and set the date and time format to NSDateIntervalFormatterFullStyle, the duration has the following format: Thursday, March 5, 2015, 4:51:36 PM GMT-05:00 - Thursday, March 5, 2015, 4:52:01 PM GMT-05:00.

How can I format the duration between two dates with ISO8601 period format (or at least as "'P'yyyy'Y'M'M'd'DT'H'H'm'M's.S'S'")?


Solution

  • The class you are using, NSDateIntervalFormatter, is designed to produce intervals of the form date1 - date2, not format the time difference between two dates.

    To get what you are after you need to use NSCalendar, NSDateComponents and stringWithFormat: (or similar).

    HTH