How to convert String to Date without knowing the format?
I agree with Kragen that in the general case there is no correct solution. However, if the following conditions hold, you may use the solution below:
You have a set of all possible formats
There is no ambiguity between the formats; no date expression can be successfully parsed by two of them.
Consider the following solution which iterates over a list of possible formats. This solution makes use of ThreadLocal
, in order to make date parsing efficient in a multi-threaded environment (remember that SimpleDateFormat
isn't thread safe):
public class FlexibleDateParser { private List<ThreadLocal<SimpleDateFormat>> threadLocals = new ArrayList<ThreadLocal<SimpleDateFormat>>(); public FlexibleDateParser(List<String> formats, final TimeZone tz){ threadLocals.clear(); for (final String format : formats) { ThreadLocal<SimpleDateFormat> dateFormatTL = new ThreadLocal<SimpleDateFormat>() { protected SimpleDateFormat initialValue() { SimpleDateFormat sdf = new SimpleDateFormat(format); sdf.setTimeZone(tz); sdf.setLenient(false); return sdf; } }; threadLocals.add(dateFormatTL); } } public Date parseDate(String dateStr) throws ParseException { for (ThreadLocal<SimpleDateFormat> tl : threadLocals) { SimpleDateFormat sdf = tl.get(); try { return sdf.parse(dateStr); } catch (ParseException e) { // Ignore and try next date parser } } // All parsers failed return null; } }
As noted before, you need to at least have an ordered list of pattern candidates. Once you have that, Apache DateUtils has a parseDate(String dateString, String[] patterns)
method that lets you easily try out a list of patterns on your date string, and parse it by the first one that matches:
public static Date parseDate(String str, String[] parsePatterns) throws ParseException
Parses a string representing a date by trying a variety of different parsers.
The parse will try each parse pattern in turn. A parse is only deemed successful if it parses the whole of the input string. If no parse patterns match, a ParseException is thrown.
The parser will be lenient toward the parsed date.