Skip to content

Instantly share code, notes, and snippets.

@mediabounds
Created July 23, 2012 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mediabounds/3164737 to your computer and use it in GitHub Desktop.
Save mediabounds/3164737 to your computer and use it in GitHub Desktop.
Converts an ISO8601 duration (http://en.wikipedia.org/wiki/ISO_8601#Durations) to seconds (NSTimeInterval)
- (NSTimeInterval) timeIntervalWithISO8601duration:(NSString *)duration
{
// duration is in the format "P3Y6M4DT12H30M5S" OR "P2W"
// The P simply indicates that this is a duration, this should be the first character.
// The T is the separator between the date portion (day, month, year) and the time portion (hour, minute, second).
if ([duration characterAtIndex:0]!='P') return 0;
NSScanner *iso8601duration = [NSScanner scannerWithString:duration];
iso8601duration.charactersToBeSkipped = [NSCharacterSet characterSetWithCharactersInString:@"P"];
NSTimeInterval seconds = 0;
BOOL isTimePortion = NO;
while (!iso8601duration.isAtEnd)
{
double value;
NSString *units;
char cUnit;
if ([iso8601duration scanDouble:&value])
{
if ([iso8601duration scanCharactersFromSet:[NSCharacterSet uppercaseLetterCharacterSet] intoString:&units])
{
for (int i=0; i<units.length; ++i)
{
cUnit = [units characterAtIndex:i];
switch (cUnit)
{
case 'Y': seconds+=31557600*value; break;
case 'M': seconds+=
isTimePortion ? 60*value
: 2629800*value; break;
case 'W': seconds+=604800*value; break;
case 'D': seconds+=86400*value; break;
case 'H': seconds+=3600*value; break;
case 'S': seconds+=value; break;
case 'T': isTimePortion=YES; break;
}
}
}
}
else break;
}
return seconds;
}
@dougboutwell
Copy link

dougboutwell commented Sep 9, 2016

Thanks! Used this to parse duration strings from the YouTube API for a Cocoa app. One minor bug - durations that begin with "PT", like YouTube's, always return 0 because the first conditional fails. Fixed like so:

--- snip --- 
    NSString *units;
    char cUnit;

        if ([iso8601duration scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"T"] intoString:&units]){
            isTimePortion = YES;
        }

        if ([iso8601duration scanDouble:&value]){
--- snip ---

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment