如何以编程方式检查字符串的日期格式以获取正确的格式

Pav*_*van 2 objective-c nsdate nsdateformatter ios ios7

以这个时间戳为例。 1993-11-14T00:00:00.000Z

我尝试使用以下日期格式来尝试将字符串转换为NSDate对象,但是由于没有提供正确的格式,所以我一直失败。无论如何,是否要进行程序检查,或者是解析器会为我自动执行此检查?

NSDateFormatter *inputDateFormat = [[NSDateFormatter alloc] init];
//Not correct format
[inputDateFormat setDateFormat:@"yyyy-MM-ddTHH:mm:ssZ"];
self.usersBirthDate = [inputDateFormat dateFromString:[dictionary objectForKey:@"birth_date"]];
Run Code Online (Sandbox Code Playgroud)

}

Rob*_*Rob 5

您应该识别并使用正确的格式字符串。在这种情况下,正确的格式字符串是:

yyyy-MM-dd'T'HH:mm:ss.SSSZ
Run Code Online (Sandbox Code Playgroud)

请注意,单引号T将括起来,并.SSS在末尾加上毫秒。顺便说一句,不要忘记locale按照技术问答QA1480中的设置进行设置。


为回答您的问题,一个有前途的替代方法是使用NSDataDetector的类型NSTextCheckingTypeDate。令人惊讶的是,它实际上捕获了许多ISO 8601 / RFC 3339日期排列。可悲的是,它不能以毫秒为单位处理排列。

但是,编写符合您所描述内容的例程并不难。您可以使用正则表达式,例如:

- (NSDate *)dateFromString:(NSString *)string {
    static NSArray *formatStrings = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatStrings = @[@{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}$",    kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ss.SSS"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",             kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ss"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$",   kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ss.SSSZ"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$",            kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ssZ"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[A-Z]{3}$",     kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ssz"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2} [A-Z]{3}$",    kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ss z"},
                          @{kDateFormatRegex: @"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2} [+|-]\\d{4}$", kDateFormatString: @"yyyy-MM-dd'T'HH:mm:ss Z"}];
    });

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
    for (NSDictionary *dictionary in formatStrings) {
        if ([string rangeOfString:dictionary[kDateFormatRegex] options:NSRegularExpressionSearch].location != NSNotFound) {
            formatter.dateFormat = dictionary[kDateFormatString];
            return [formatter dateFromString:string];
        }
    }

    return nil;
}
Run Code Online (Sandbox Code Playgroud)

综上所述,这似乎是一个非常低效的过程:令我惊讶的是,最好知道您的Web服务将用于日期的格式,并为此使用适当的格式字符串。但是,如果您想以编程方式检测模式,则可以使用上述正则表达式。只需扩展该词典formatStrings以包括您关心的所有可能排列。