views:

106

answers:

2

I'm parsing third party log files containing date/time using Joda. The date/time is in one of two different formats, depending on the age of the log files I'm parsing.

Currently I have code like this:

try {
    return DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss").parseDateTime(datePart);
} catch (IllegalArgumentException e) {
    return DateTimeFormat.forPattern("E, MMM dd, yyyy HH:mm").parseDateTime(datePart);
}

This works but contravenes Joshua Bloch's advice from Effective Java 2nd Edition (Item 57: Use exceptions only for exceptional conditions). It also makes it hard to determine if an IllegalArgumentException occurs due to a screwed up date/time in a log file.

Can you suggest a nicer approach that doesn't misuse exceptions?

+3  A: 

Unfortunately I don't believe Joda Time has any such capabilities. It would be nice to have a "tryParseDateTime" method, but it doesn't exist.

I suggest you isolate this behaviour into your own class (one which takes a list of patterns, and will try each in turn) so that the ugliness is only in one place. If this is causing performance issues, you might want to try to use some heuristics to guess which format to try first. For example, in your case if the string starts with a digit then it's probably the first pattern.

Note that DateTimeFormatters in Joda Time are conventionally immutable - you shouldn't be creating a new one each time you want to parse a line. Create them once and reuse them.

Jon Skeet
This answer gives a sense to my comment. I'm pretty satisfied :)I'm still a beginner, so I would not give it as answer
Sylvain M
Thanks Jon. I knew about DateTimeFormatters being immutable, but for the sake of brevity in my code example created them explicitly.There are no intolerable performance issues, so I think I'll do what you suggest and create a class to hide the ugliness.
Steve McLeod
+1  A: 

Joda-Time supports this by allowing multiple parsers to be specified - DateTimeFormatterBuilder#append

Simply create your two formatters using a builder and call toParser() on each. Then use the builder to combine them using append.

JodaStephen
Whoa! Answered directly from the man himself! Love your work Stephen.
Steve McLeod
Hmm, I tried this, but Joda-Time then seems to expect the string being parsed to match a pattern that consists of BOTH the patterns appended together, rather than one OR the other.
Steve McLeod
Perhaps the forum is a better location to see if this is a bug - http://sourceforge.net/projects/joda-time/forums/forum/337835
JodaStephen