In Java, we play a lot with Dates. Here’s one more scenario. You have a string which has date in it. You want to convert it into a valid java.util.Date
object. Now in Java you can convert a String to Date using SimpleDateFormat class. But we will add a little more complexity on that. Lets say the date format in String is not fixed. User might enter date in format “dd/mm/yyy” or “dd-mm-yyyy” or “dd.mmm.yy”! In any of such case we should get a valid java.util.Date
object. Here’s a simple Util class that you can use to convert String having date in multiple formats to java.util.Date object.
package net.viralpatel.java;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DateUtil {
// List of all date formats that we want to parse.
// Add your own format here.
private static List<SimpleDateFormat>;
dateFormats = new ArrayList<SimpleDateFormat>() {{
add(new SimpleDateFormat("M/dd/yyyy"));
add(new SimpleDateFormat("dd.M.yyyy"));
add(new SimpleDateFormat("M/dd/yyyy hh:mm:ss a"));
add(new SimpleDateFormat("dd.M.yyyy hh:mm:ss a"));
add(new SimpleDateFormat("dd.MMM.yyyy"));
add(new SimpleDateFormat("dd-MMM-yyyy"));
}
};
/**
* Convert String with various formats into java.util.Date
*
* @param input
* Date as a string
* @return java.util.Date object if input string is parsed
* successfully else returns null
*/
public static Date convertToDate(String input) {
Date date = null;
if(null == input) {
return null;
}
for (SimpleDateFormat format : dateFormats) {
try {
format.setLenient(false);
date = format.parse(input);
} catch (ParseException e) {
//Shhh.. try other formats
}
if (date != null) {
break;
}
}
return date;
}
}
Code language: Java (java)
The above code has a list of SimpleDateFormat
objects that holds different valid date formats that you want to parse. Add a new format if you want your code to parse it. Also check the convertToDate()
method. It runs through each format from the list and check weather input string is valid date or not. If it is successful in converting String to Date, it returns the Date object. If it fails to convert String to Date then it returns null. Let’s test this with various input:
package net.viralpatel.java;
public class TestDateUtil {
public static void main(String[] args) {
System.out.println("10/14/2012" + " = " + DateUtil.convertToDate("10/14/2012"));
System.out.println("10-Jan-2012" + " = " + DateUtil.convertToDate("10-Jan-2012"));
System.out.println("01.03.2002" + " = " + DateUtil.convertToDate("01.03.2002"));
System.out.println("12/03/2010" + " = " + DateUtil.convertToDate("12/03/2010"));
System.out.println("19.Feb.2011" + " = " + DateUtil.convertToDate("19.Feb.2011" ));
System.out.println("4/20/2012" + " = " + DateUtil.convertToDate("4/20/2012"));
System.out.println("some string" + " = " + DateUtil.convertToDate("some string"));
System.out.println("123456" + " = " + DateUtil.convertToDate("123456"));
System.out.println("null" + " = " + DateUtil.convertToDate(null));
}
}
Code language: Java (java)
Output:
10/14/2012 = Sun Oct 14 00:00:00 CEST 2012
10-Jan-2012 = Tue Jan 10 00:00:00 CET 2012
01.03.2002 = Fri Mar 01 00:00:00 CET 2002
12/03/2010 = Fri Dec 03 00:00:00 CET 2010
19.Feb.2011 = Sat Feb 19 00:00:00 CET 2011
4/20/2012 = Fri Apr 20 00:00:00 CEST 2012
some string = null
123456 = null
null = null
Code language: JavaScript (javascript)
Thus you can quickly check weather given string is a valid Date or not using DateUtil class.
Update: SimpleDateFormat and Thread Safety
Many developers have commented on this post about the issue of Thread safety in this code snippet. As SimpleDateFormat class itself is not thread safe it can cause issues in production. Here’s a workaround for this problem. Instead of SimpleDateFormat
class in above utility method, use below ThreadSafeSimpleDateFormat
class. This will solve the problem of Thread safety.
package net.viralpatel.java;
public class ThreadSafeSimpleDateFormat {
private DateFormat df;
public ThreadSafeSimpleDateFormat(String format) {
this.df = new SimpleDateFormat(format);
}
public synchronized String format(Date date) {
return df.format(date);
}
public synchronized Date parse(String string) throws ParseException {
return df.parse(string);
}
}
Code language: Java (java)
Thanks for your valuable comments :)
Try “DateUtil.convertToDate(“10/14/2012/01/01″)”
Hi Not Relevant,
SimpleDateFormat by default is set to Lenient true. Check here the javadoc. If you want to avoid such conditions, just add
format.setLenient(true)
right before you parse the date. It won’t consider the format 10/14/2012/01/01.Give it a try first. Here’s the code again:
Ops, my bad.. I meant
By default SimpleDateFormat set Lenient to true. So we should set it false if we want strict checkup.
one more thing. frm java doc abouyt simpleDateFormat
Synchronization
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
Just keep in mind
Using date format with separators is realy simple, but how would you deal with format like “ddMMyy”?
And user input like : “11111”. it could be both 1.11.2001 and 11.1.2011 :-)
Even if you set lenient to false, a format like “dd.MM.yyyy” will happily accept a two-digit year with possibly surprising results. The solution i’ve seen at almost every company I worked with was to accompany every date format with a corresponding regex. The regex is checked first to unambiguously map the input to the appropriate date format.
Hi Frisian, Can you share a snippet for that! Would be interesting to check.
Hi Viral,
I’m under NDA, but I am probably allowed to outline the matching:
For the date format “dd.MM.yyyy”, the equivalant regex would be “\\d\\d[.]\\d\\d[.]\\d\\d\\d\\d”.
The code inside a loop for the different date formats would look something like this:
The problem with the non-thread-safe SimpleDateFormat is solved as well.
That is not thread safe and will cause inconsistent results when . You are going to wreck someones month if you don’t put a disclaimer on that it is not production ready
Hi, I understand that the code isn’t thread safe. But I presented here it in its entirety for reference purpose. Anyways, I have updated the post and added a new “Thread Safe” version which will solve this issue.
Thanks,
Viral
sir I want to convert a date which is in String format of “dd/mm/yyyy” . now I want to convert this string in ‘dd/MON/yy” as a Date in Java.
Example: “19/04/2013” should be converted in 19/APR/13 in Java
Isn’t there any other alternative to it because this seems to be an awkward practice (don’t take my wrong) because in any situation, we need to try our level best to prevent an exception to occur.
Thanks.
Hi,
I want to do a filename validation that has date in it. For Example, Mad20131222.txt .. i.e. Date should be in format YYYYMMDD. Appreciate your help in this regard
Thanks!
consider this case…
You have set the date format as dd-mm-yyyy
however your input string is “08-09-2014 any junk afterwards”
This input string will also get processed, try it out.
Let me know what are your thoughts about how to handle this ?
You need to manually cover it: check the string’s length and also check char’s (allow only digits and “-“)
how to check date ranges like below in YYYYMMDD format in java
1900 < YYYY
01 <= MM <= 12
01 <= DD <= end day of the month
Time is not getting printed with this code.
I apologise, this is working good.