Question

How can I parse a string that represents a date and/or time using iPhone SDK if I do not know the format? I am building an application that will allow a range of possible dates and times to be used, and I don't want it to fail because the format was "01/01/2001" instead of "01-01-2001", etc. Time may or may not be included.

Is there any way to do this? I have tried using NSDateFormatter with date and time styles set to "NoStyle", and setLenient = YES, but it still fails to parse the simplest of strings: "1/22/2009 12:00:00 PM"

I have no way of knowing the format in advance, I need a method that will heuristically determine the format.

I am coming from a .NET background, where this is as simple as new DateTime(string_in_any_format); but I have no idea how to do this in Obj-C.

Was it helpful?

Solution

Unfortunately, NSDateFormatter on the iPhone isn't that smart. You need to give it a little guidance. When you set both the date and time styles to NoStyle it expects to see neither a date nor time. You'll need at least one of them set to some other style. You can do something like the following and it should work fine (it does for me).

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

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

NSLog(@"%@", date);

OTHER TIPS

Old post, but there are better ways to handle this that I found on other posts.

You can use a method like this:

  • First, try and parse the date in a couple of expected formats.
  • If that doesn't work, use NSDataDetector to try and find date information (reference: this SO post).

Here's a sample of code I used for this (I expected a couple date formats, but couldn't be certain that's the only date I'd ever see and didn't want to fail if possible):

// 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 :(

How would your potential parser determine if 01/02/10 is jan 2, 2010; feb 1, 2010; or something entirely different? Bboth mm/dd/yy and dd/mm/yy are reasonable to expect, depending on where your customers are.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top