如何将人类可读时间表达式(NSString)解析为NSTimeInterval?

时间:2013-03-03 16:12:50

标签: objective-c parsing time expression

所以说我有一个NSString,它有一个人类可读的时间表达式,如@“10分钟”或@“2小时”。有没有一个客观的C库可以帮我解析为NSTimeInterval? (或者我可以在iOS应用程序中轻松使用的C库或其他任何东西)。

我编写了一个处理简单案例的方法。上面的简单案例并不太难,如果没有人提出任何建议,那就是我将采取的方向。但是我的代码对输入做了很多假设。我的代码目前不会解析@“十分半钟”或@“5 horas”。 (与往常一样,日期和时间函数总是比它们第一次出现时更难。)

我已经在Google,Stack Exchange和GitHub上进行了一些搜索,但到目前为止我发现的唯一内容是解析日期(不是时间间隔)和解析ISO-8601持续时间(假设非常具体的输入) )。

1 个答案:

答案 0 :(得分:0)

对于它的价值,我想我会发布我最终使用的代码。它并没有真正回答这个问题,因为它只处理非常简单的情况。对于我的用例来说它已经足够好了,但我仍然希望看到一个更强大的库。

+ (NSTimeInterval)timeIntervalFromString:(NSString *)string {
    NSTimeInterval interval    = 0.0;
    NSError *error = NULL;
    NSString *pattern          = @"^\\s*(\\d+)\\s+(second|minute|hour|day)s?\\s*$";
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    NSTextCheckingResult *matchResult = [regex firstMatchInString:string
                                                          options:NSMatchingAnchored
                                                            range:NSMakeRange(0, [string length])];

    if(matchResult != nil) {
        NSString *numberString = [string substringWithRange:[matchResult rangeAtIndex:1]];
        NSString *unitString   = [string substringWithRange:[matchResult rangeAtIndex:2]];

        if([[unitString lowercaseString] isEqualToString:@"second"]) {
            interval = [numberString floatValue];
        } else if([[unitString lowercaseString] isEqualToString:@"minute"]) {
            interval = [numberString floatValue] * 60;
        } else if([[unitString lowercaseString] isEqualToString:@"hour"]) {
            interval = [numberString floatValue] * 3600;
        } else if([[unitString lowercaseString] isEqualToString:@"day"]) {
            interval = [numberString floatValue] * 3600 * 24;
        }
    }
    return interval;
}