Using Joda Date & Time API to parse multiple formats
Solution 1
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" );
Solution 2
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
.
Solution 3
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 DateTimeFormatter
s 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.
Related videos on Youtube
Steve McLeod
Java is my thing. I run Barbary Software, a tiny software company in Barcelona, Spain. Our products are Feature Upvote, a SaaS tool for feature request tracking, and Saber Feedback, a feedback widget for any website.
Updated on July 05, 2022Comments
-
Steve McLeod almost 2 years
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?
-
sly7_7 almost 14 yearsPerhaps by guessing the pattern before using it.
-
-
sly7_7 almost 14 yearsThis answer gives a sense to my comment. I'm pretty satisfied :) I'm still a beginner, so I would not give it as answer
-
Steve McLeod almost 14 yearsThanks 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 almost 14 yearsWhoa! Answered directly from the man himself! Love your work Stephen.
-
Steve McLeod almost 14 yearsHmm, 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.
-
JodaStephen almost 14 yearsPerhaps the forum is a better location to see if this is a bug - sourceforge.net/projects/joda-time/forums/forum/337835
-
Steve McLeod over 13 yearsThis works perfectly. I guess JodaStephen meant this to, but when I tried to do things according to his instructions the parsing failed.
-
Steven about 10 yearsThis 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.
-
shmosel about 6 yearsStrangely, despite the variety of
append
overloads, this is the only one that doesn't throw an exception when given conflicting formats. -
granadaCoder over 5 yearsBoo 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