80

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?

1
  • Perhaps by guessing the pattern before using it. Commented Jul 22, 2010 at 9:21

3 Answers 3

149

You can create multiple parsers and add them to the builder by using DateTimeFormatterBuilder.append method:

DateTimeParser[] parsers = { 
        DateTimeFormat.forPattern( "yyyy-MM-dd HH" ).getParser(),
        DateTimeFormat.forPattern( "yyyy-MM-dd" ).getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append( null, parsers ).toFormatter();

DateTime date1 = formatter.parseDateTime( "2010-01-01" );
DateTime date2 = formatter.parseDateTime( "2010-01-01 01" );
Sign up to request clarification or add additional context in comments.

3 Comments

This works perfectly. I guess JodaStephen meant this to, but when I tried to do things according to his instructions the parsing failed.
This does not work for for example '5-5-5' and '5-5-2005' if you want both dd-MM-yy and dd-MM-yyyy (could not parse exception). Later I found out that dd-MM-yy also parses dd-MM-yyyy just fine, so that resolved my problem.
Strangely, despite the variety of append overloads, this is the only one that doesn't throw an exception when given conflicting formats.
19

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.

3 Comments

Whoa! Answered directly from the man himself! Love your work Stephen.
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.
Perhaps the forum is a better location to see if this is a bug - sourceforge.net/projects/joda-time/forums/forum/337835
7

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.

3 Comments

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
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.
Boo Java for lack of TryParse functions like DotNet. The lack of tryParse routines and generic type erasure are my two biggest gripes. docs.oracle.com/javase/tutorial/java/generics/erasure.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.