Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse an ISO-8601 duration in Objective C?

I'm looking for an easy way to parse a string that contains an ISO-8601 duration in Objective C. The result should be something usable like a NSTimeInterval.

An example of an ISO-8601 duration: P1DT13H24M17S, which means 1 day, 13 hours, 24 minutes and 17 seconds.

like image 492
Zargony Avatar asked Jul 18 '09 01:07

Zargony


2 Answers

Swift3,4,5 implementation: https://github.com/Igor-Palaguta/YoutubeEngine/blob/master/Source/YoutubeEngine/Parser/NSDateComponents%2BISO8601.swift

Example: let components = try DateComponents(ISO8601String: "P1Y2M3DT4H5M6S")

Tests: https://github.com/Igor-Palaguta/YoutubeEngine/blob/master/Tests/YoutubeEngineTests/ISO8601DurationTests.swift

Update: fixed for DougSwith case "P3W3DT20H31M21"

like image 52
Igor Palaguta Avatar answered Sep 22 '22 03:09

Igor Palaguta


A pure Objective C version...

NSString *duration = @"P1DT10H15M49S";

int i = 0, days = 0, hours = 0, minutes = 0, seconds = 0;

while(i < duration.length)
{
    NSString *str = [duration substringWithRange:NSMakeRange(i, duration.length-i)];

    i++;

    if([str hasPrefix:@"P"] || [str hasPrefix:@"T"])
        continue;

    NSScanner *sc = [NSScanner scannerWithString:str];
    int value = 0;

    if ([sc scanInt:&value])
    {
        i += [sc scanLocation]-1;

        str = [duration substringWithRange:NSMakeRange(i, duration.length-i)];

        i++;

        if([str hasPrefix:@"D"])
            days = value;
        else if([str hasPrefix:@"H"])
            hours = value;
        else if([str hasPrefix:@"M"])
            minutes = value;
        else if([str hasPrefix:@"S"])
            seconds = value;
    }
}

NSLog(@"%@", [NSString stringWithFormat:@"%d days, %d hours, %d mins, %d seconds", days, hours, minutes, seconds]);
like image 25
headkaze Avatar answered Sep 24 '22 03:09

headkaze