2010-08-14 39 views
2

如何解析表示日期和/或时间使用iPhone SDK的字符串,如果我不知道格式?我正在构建一个允许使用一系列可能的日期和时间的应用程序,我不希望它失败,因为格式是“01/01/2001”而不是“01-01-2001”等。时间可能会或可能不会被包括在内。如何解析iphone上的未知格式的日期字符串?

有没有办法做到这一点?我曾尝试使用日期和时间样式设置为“NoStyle”和setLenient = YES的NSDateFormatter,但它仍然无法解析最简单的字符串:“2009年1月22日中午12:00:00”

I无法预先知道格式,我需要一种能够启发式确定格式的方法。

我来自.NET的背景,这就像新的DateTime(string_in_any_format)一样简单;但我不知道如何在Obj-C中做到这一点。

回答

4

不幸的是,iPhone上的NSDateFormatter不是聪明。你需要给它一点指导。当您将日期和时间样式设置为NoStyle时,它预计不会看到日期和时间。你至少需要其中一个设置为其他风格。你可以做下面的事情,它应该可以正常工作(它对我来说)。

NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateStyle:NSDateFormatterLongStyle]; 
[formatter setTimeStyle:NSDateFormatterNoStyle]; 
[formatter setLenient:YES]; 

NSDate * date = [formatter dateFromString:@"01-01/2001"]; 

NSLog(@"%@", date); 
+0

谢谢你的帮助。我可以看到,这将是一个有用的建设,但由于它似乎没有提供,我会建立自己的。目前我只会支持有限的格式。 – 2010-08-14 22:04:13

0

您的潜在解析器将如何确定01/02/10是否是2010年1月2日; 2010年2月1日;或者完全不同的东西? Bboth mm/dd/yy和dd/mm/yy是合理的预期,取决于您的客户在哪里。

+0

解析器可以采用一种格式或基于语言环境的其他格式,因此可以接受这种假设。然而,这是唯一可以接受的假设。 – 2010-08-15 16:37:42

+0

因此,基本上你要求的是如何使解析器不会在 - 和/?之间产生任何区别。 – erikkallen 2010-08-15 17:32:40

2

旧的帖子,但有更好的方法来处理,我发现在其他职位上。

可以使用的方法是这样的:

  • 首先,尝试解析日期一对夫妇预期的格式。
  • 如果这不起作用,请使用NSDataDetector来尝试查找日期信息(参考:this SO post)。

下面是我用这个代码样本(我希望一对夫妇的日期格式,但无法确定这就是我所看到的唯一日期,并没有想如果可能的失败):

// your date formats may vary, the OP might try "MM/dd/yyyy" and "MM-dd-yyyy", along with combos that include time info 
NSArray *dateFormatsToTry = @[@"yyyy-MM-dd'T'HH:mmZZZZ", @"yyyy-MM-dd'T'HH:mm:ssZZZ"]; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; 

for (NSString * format in dateFormatsToTry) { 
    [dateFormatter setDateFormat:format]; 
    NSDate *date = [[[self class] sharedDateFormatter] dateFromString:dateString]; 
    if (date) { 
     return date; 
    } 
} 

// try and figure out the date if the all of the expected formats failed to 
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeDate error:nil]; 
NSTextCheckingResult *result = [detector firstMatchInString:dateString options:0 range:NSMakeRange(0, [dateString length])]; 
if ([result resultType] == NSTextCheckingTypeDate) { 
    NSDate * date = [result date]; 
    if (date) { 
     return date; 
    } 
} 

return [NSDate date]; // default to now :(