2

Possible Duplicate:
Converting mutliple date format into a single format in iPhone

I am trying to parse an RSS and extract an NSString for dates from the content section of the RSS, and convert it to an NSDate. Here is what I have so far:

The RSS content always will list times as When: Date/Time to ending time. I first scan each item in the RSS to get me what is in between the When: and the 'to' part. I then set a NSDateFormatter. Here is where the issue is. Sometimes it is listed as Thu Sep 6, 2013 1:00PM but in other times, the format used is Thu Sep 6, 2013 1pm. So...the issue I need to solve is setting something up so that no matter the format of date, it is able to return something, because now using "EEE MMM dd, yyyy h:mma" is leaving out the instances where the feed just says 1pm.

NSMutableArray *substrings = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:articleImage];
[scanner scanUpToString:@"When: " intoString:nil]; // Scan all characters before #

NSString *substring = nil;
[scanner scanString:@"When: " intoString:nil]; // Scan the # character
if([scanner scanUpToString:@" to" intoString:&substring]) {
    // If the space immediately followed the #, this will be skipped
    //[substrings addObject:substring];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    // this is imporant - we set our input date format to match our input string
    // if format doesn't match you'll get nil from your string, so be careful
    [dateFormatter setDateFormat:@"EEE MMM dd, yyyy h:mma"];
    NSDate *dateFromString = [[NSDate alloc] init];
    // voila!
    dateFromString = [dateFormatter dateFromString:substring];
    self.thetruedate = dateFromString;
    [dateFormatter release];
    NSLog(@"%@",dateFromString);
    [substrings release];
}
Community
  • 1
  • 1
user717452
  • 33
  • 14
  • 73
  • 149
  • @ACB I don't understand the answer given in that question you linked to. How do I call that method while parsing everything else in the RSS? – user717452 Jan 25 '13 at 19:37
  • Instead of using the date formatter in your question, you need to use it as `[self dateStringFromString:substring destinationFormat:@"dd-MM-yyyy"]);` Here you can define any destination format you want or convert it to NSDate and use it. That method definition is already there in the accepted answer. You might have to include your possible date formats in that. – iDev Jan 25 '13 at 19:40
  • 1
    I'm not following you at all @ACB How about posting something as an answer so I can see it better than what comments allows. – user717452 Jan 25 '13 at 19:42
  • Check my answer. I have used the same method, but modified to return NSDate instead of NSString. – iDev Jan 25 '13 at 19:48

2 Answers2

3

Define a method with all possible date formats in your RSS as,

- (NSDate *)dateFromSourceString:(NSString *)sourceString {

    NSDate *convertedDate = nil;
    NSArray *dateFormatterList = [NSArray arrayWithObjects:@"EEE MMM dd, yyyy h:mma", 
                                  @"EEE MMM dd, yyyy ha", nil];//include all possible dateformats here

    //sourceString = @"Thu Sep 6, 2013 1:00PM";

    if (sourceString) {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

        for (NSString *dateFormatterString in dateFormatterList) {

            [dateFormatter setDateFormat:dateFormatterString];
            NSDate *originalDate = [dateFormatter dateFromString:sourceString];

            if (originalDate) {

                convertedDate = originalDate;
                NSLog(@"Converted date is %@", convertedDate);
                break;
            }
        }
       [dateFormatter release]; //release it if it is a non-arc project
    }

    return convertedDate;
}

And then use it as,

NSMutableArray *substrings = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:articleImage];
[scanner scanUpToString:@"When: " intoString:nil]; // Scan all characters before #

NSString *substring = nil;
[scanner scanString:@"When: " intoString:nil]; // Scan the # character
if([scanner scanUpToString:@" to" intoString:&substring]) {
    // If the space immediately followed the #, this will be skipped
    //[substrings addObject:substring];

    // this is imporant - we set our input date format to match our input string
    // if format doesn't match you'll get nil from your string, so be careful

    NSDate *dateFromString = [self dateFromSourceString:substring];
    self.thetruedate = dateFromString;
    NSLog(@"%@",dateFromString);
    [substrings release];
}

dateFromSourceString method will pick date formatters from dateFormatterList and will try to convert to date. If the format is incorrect, it will return nil. This can be used in your case.

iDev
  • 23,310
  • 7
  • 60
  • 85
  • Thx. I had set ~NSDate *dateFromString = [self dateFromSourceString:substring];~ incorrectly and it was returning just the current time. This works! – user717452 Jan 25 '13 at 19:54
  • Had one last issue creep in. I thought that every item included basic format of When: Date Time to Time. It seems that some of them simply have the date without the time. Since those don't include the word 'to' they do't get added into substrings, and the date is never parsed. Any suggestions on that end? – user717452 Jan 25 '13 at 20:22
  • Is there any other delimiter instead of to? something like a dot or so? – iDev Jan 25 '13 at 20:26
  • Seems there are 3 possibilities of how the entry is displayed:1. When: Date/Time to end time. 2. When: Date Where: Event Status: 3. When: Date Event Status: Just not sure how to tell the scanner to check them all instead of returning null. – user717452 Jan 25 '13 at 20:27
  • They do all have the year, but I don't want to limit it to one year, as some entries are still 2012 some 2013 and some will probably be 2014 in future – user717452 Jan 25 '13 at 20:28
  • Check this tutorial to find out how they are fetching date from rss feed. http://gigaom.com/2008/08/04/tutorial-build-a-simple-rss-reader-for-iphone/. If these are not helping, how about posting a new question asking how to fetch date string from rss. There could be different approach than using scanners. – iDev Jan 25 '13 at 20:30
  • Scanners is my last ditch effort. The feed comes from google calendars which inexplicably has NO RSS tags for the date the event occurs, but only tags for when the event was published to the RSS feed itself. This is why I resorted to scanners. – user717452 Jan 25 '13 at 20:33
  • One more thing, if you are getting _" Where:" or " Event Status:"_ instead of _" to:"_ why dont you change your if condition to include all these three conditions? – iDev Jan 25 '13 at 20:34
  • How can I do that to check for all 3? – user717452 Jan 25 '13 at 20:40
  • I dont have much experience with scanners. But is it possible to check for `substring == null` inside `if([scanner scanUpToString:@" to" intoString:&substring]) {` and then add an if condition as `if([scanner scanUpToString:@" Where:" intoString:&substring])` so that if first one couldnt fetch it the second if condition can fetch that? Same for other one as well – iDev Jan 25 '13 at 20:55
  • Only problem is that the substring doesn't actually go to null, now that I look closely at it. It just doesn't have an end date for the scanner when 'to' is not present, so the substring is the date AND everything past it. I tried running some code that if certain characters existed in the substring to run the code again, but no luck on that. – user717452 Jan 25 '13 at 21:24
  • In that case you might have to create a new scanner inside that if condition(Use the substring for scanning now) to locate _" To"_ and if that scanner is not returning true, you might have to scan for other 2 conditions. If one of them is correct you need to get a new substring from this actual string. – iDev Jan 25 '13 at 21:28
  • I think I have a solution that would return date and time for all entries, but I can't find the right dateFormatter for this: ~Fri Jan 11, 2013 10:15am to 12pm  CST~ In console, it shows a dot that is centered in the line (like a period floating in the line) before the line break and time zone. I have tried adding this to the date formatter: ~@"EEE MMM dd, yyyy h:mma 'to' h:mma ZZZ"~ but no luck there either – user717452 Jan 25 '13 at 21:29
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/23391/discussion-between-acb-and-user717452) – iDev Jan 25 '13 at 21:31
  • I found a common delimiter for the scanner, but there are some entries where the time is displayed like this: Thu Sep 20, 2012 9:45am to 10:15am CDT (XCode console shows a middle dot between am and CDT) – user717452 Jan 25 '13 at 21:41
  • This is exactly what i suggested but i didn't code. Any ways this is good, will come handy for me in future :) – Anoop Vaidya Jan 26 '13 at 19:26
  • Yes, glad to see that after I posted the link to duplicate question which had the same answer as you said below(I posted with code there, that too a few months back), you posted its logic here. – iDev Jan 26 '13 at 19:46
0

You can create all possible types of date format available in your RSS.

Keep on converting by each date formatter one by one, until the converted date is not null. As invalid format will fail to convert and return a null.

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140