Zar*_*ony 14 iphone datetime objective-c iso8601 nstimeinterval
我正在寻找一种简单的方法来解析在Objective C 中包含ISO-8601 持续时间的字符串.结果应该是像a一样可用的东西NSTimeInterval
.
ISO-8601持续时间的一个示例:P1DT13H24M17S
表示1天,13小时,24分钟和17秒.
hea*_*aze 10
一个纯粹的Objective C版本......
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]);
Run Code Online (Sandbox Code Playgroud)
此版本解析每个youtube持续时间没有错误.
重要提示:此版本使用ARC.
- (NSString*)parseISO8601Time:(NSString*)duration
{
NSInteger hours = 0;
NSInteger minutes = 0;
NSInteger seconds = 0;
//Get Time part from ISO 8601 formatted duration http://en.wikipedia.org/wiki/ISO_8601#Durations
duration = [duration substringFromIndex:[duration rangeOfString:@"T"].location];
while ([duration length] > 1) { //only one letter remains after parsing
duration = [duration substringFromIndex:1];
NSScanner *scanner = [[NSScanner alloc] initWithString:duration];
NSString *durationPart = [[NSString alloc] init];
[scanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] intoString:&durationPart];
NSRange rangeOfDurationPart = [duration rangeOfString:durationPart];
duration = [duration substringFromIndex:rangeOfDurationPart.location + rangeOfDurationPart.length];
if ([[duration substringToIndex:1] isEqualToString:@"H"]) {
hours = [durationPart intValue];
}
if ([[duration substringToIndex:1] isEqualToString:@"M"]) {
minutes = [durationPart intValue];
}
if ([[duration substringToIndex:1] isEqualToString:@"S"]) {
seconds = [durationPart intValue];
}
}
return [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
}
Run Code Online (Sandbox Code Playgroud)
Swift2实现:https://github.com/Igor-Palaguta/YoutubeEngine/blob/swift-2.3/YoutubeEngine/Classes/Parser/NSDateComponents+ISO8601.swift
例:
let components = NSDateComponents(ISO8601String: "P1Y2M3DT4H5M6S")
测试:https://github.com/Igor-Palaguta/YoutubeEngine/blob/swift-2.3/Example/Tests/ISO8601DurationTests.swift
它还正确处理"P1M"和"PT1M"情况
Swift3实现:https: //github.com/Igor-Palaguta/YoutubeEngine/blob/master/Source/YoutubeEngine/Parser/NSDateComponents%2BISO8601.swift
例:
let components = dateComponents(ISO8601String: "P1Y2M3DT4H5M6S")
测试:https: //github.com/Igor-Palaguta/YoutubeEngine/blob/master/Tests/YoutubeEngineTests/ISO8601DurationTests.swift
2017年1月20日更新:增加了数周的支持
如果您确切知道将要获得哪些字段,则可以使用以下调用sscanf()
:
const char *stringToParse = ...;
int days, hours, minutes, seconds;
NSTimeInterval interval;
if(sscanf(stringToParse, "P%dDT%dH%dM%sS", &days, &hours, &minutes, &seconds) == 4)
interval = ((days * 24 + hours) * 60 + minutes) * 60 + seconds;
else
; // handle error, parsing failed
Run Code Online (Sandbox Code Playgroud)
如果可以省略任何字段,则需要在解析时更加智能,例如:
const char *stringToParse = ...;
int days = 0, hours = 0, minutes = 0, seconds = 0;
const char *ptr = stringToParse;
while(*ptr)
{
if(*ptr == 'P' || *ptr == 'T')
{
ptr++;
continue;
}
int value, charsRead;
char type;
if(sscanf(ptr, "%d%c%n", &value, &type, &charsRead) != 2)
; // handle parse error
if(type == 'D')
days = value;
else if(type == 'H')
hours = value;
else if(type == 'M')
minutes = value;
else if(type == 'S')
seconds = value;
else
; // handle invalid type
ptr += charsRead;
}
NSTimeInterval interval = ((days * 24 + hours) * 60 + minutes) * 60 + seconds;
Run Code Online (Sandbox Code Playgroud)