Parsing Email Date Formats

I’ve been busily working towards the release of LicenseKeeper 1.2 over the past week. This morning I attacked a minor issue where some email received dates weren’t being parsed correctly.

After some investigation, it turns out that is was just a matter of handling an additional string to date conversion format. The problem and solution were fairly trivial, but my first and very lazy approach oozed ugly:

// Apple Mail style date... 
//      (ex: Sat, 24 Mar 2007 21:51:06 +0100)
_dateReceived = [NSCalendarDate dateWithString:dateString 
                   calendarFormat:@"%a, %d %b %Y %I:%M:%S %z"];
if (!_dateReceived) {
   // Entourage style date... 
   //   (ex: Tuesday, March 13, 2007 3:46 PM)
   _dateReceived = [NSCalendarDate dateWithString:dateString 
                   calendarFormat:@"%A, %B %e, %Y %I:%M %p"];
}
if (!_dateReceived) {
   // short style date with no time zone... 
   //   (ex: Fri, 1 Jun 2007 14:24:56)
   _dateReceived = [NSCalendarDate dateWithString:dateString 
                   calendarFormat:@"%a, %d %b %Y %I:%M:%S"];
}

Originally, I just had two date formats to parse so one “if” statement didn’t look to bad. But, it also had some nasty hard coded string constants.

Once I added the third date format, the code really started to look ugly and started to reek of code rot: too many hard-coded strings and cut-and-paste code blocks.

So, I refactored the code to move the date format strings to the application’s Info.plist file:

OLEmailDateFormats
      
            %a, %d %b %Y %I:%M:%S %z
            %A, %B %e, %Y %I:%M %p
            %a, %d %b %Y %I:%M:%S
       

Now with the date formats moved to a more manageable and reusable place, the date parsing code block cleans up quite nicely.

NSArray *dateFormats = [[[NSBundle mainBundle] infoDictionary]
                             valueForKey:@"OLEmailDateFormats"];
int i;
for (i = 0; i < [dateFormats count]; i++) {
   _dateReceived = [NSCalendarDate dateWithString:dateString 
                    calendarFormat:[dateFormats objectAtIndex:i]];
   if (_dateReceived) {
      break;
   }
}

The big advantage here is that if I need to add more date formats to the parser the code doesn’t become more complicated and run the risk of adding new bugs down the line. It also eliminates the need to recompile the source file if all I’m doing is adding a new format.

Plus the code just looks nicer and is easier to understand.

Cocoa Cheerleaders

When starting out as a Cocoa developer or switching from another platform, sometimes the hardest part is knowing where to find information about your new chosen toolset.

There are some good resources around the net, but finding them can be challenging if you don’t know what to look for.

David Masters brings us a new Cocoa centric web site with a unique theme, but don’t let that scare you off.

Cocoa Cheerleaders has a very nice growing collection of links categorized by “Sites”, “Blogs”, “Casts” or podcasts, “Books”, “Lists”, and “Code”. Each link has a cool AJAXie site preview image with a summary and RSS availability indicators.

Surfaced

I made it back from my vacation.

I’m still trying to catch up on email and the news coming out of WWDC07. But, normal response times for email and support should be back to normal.

Vacation, Support and Email Response

I will be away from the office on vacation for a week, starting Wednesday June 6. While away, support and email response will probably be delayed. Please bear with me.

The island of Ambergris Caye, Belize does have internet connectivity, but not in my hotel. I’ll try and connect once a day but this will be heavily influenced by the hours and policies of the local internet cafes (Plus, I will be on vacation).