Check if String is valid Date in Java

java-logo2

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 :)

Get our Articles via Email. Enter your email address.

You may also like...

19 Comments

  1. Not Relevant says:

    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.

      • Not Relevant says:

        Give it a try first. Here’s the code again:

        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.mm.dd");
            sdf.setLenient(true);
            Date date = null;
            try {
              date = sdf.parse("2012.11.02.45.65");
            } catch (ParseException e) {
              e.printStackTrace();
            }
            // Output: date: Mon Jan 02 00:11:00 FET 2012
            System.out.println("date: " + date);
        

        • Ops, my bad.. I meant

          setLenient(false);

          By default SimpleDateFormat set Lenient to true. So we should set it false if we want strict checkup.

  2. timoras says:

    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

  3. Frantisek says:

    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 :-)

  4. Frisian says:

    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.

      • Frisian says:

        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:

        ...
        Pattern p = Pattern.compile(regex); // thread-safe
        ...
        Matcher m = p.matcher(input);
        if (m.matches()) {
          SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
          sdf.setLenient(false);
          return sdf.parse(input);
        }
        // exception handling goes here
        ...
        

        The problem with the non-thread-safe SimpleDateFormat is solved as well.

  5. NotThreadSafe says:

    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

  6. Abhishek Prartap Singh says:

    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

  7. Gowtham says:

    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.

  8. M says:

    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!

  9. MeSh says:

    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 ?

    • access denied says:

      You need to manually cover it: check the string’s length and also check char’s (allow only digits and “-“)

  10. Anusha says:

    how to check date ranges like below in YYYYMMDD format in java

    1900 < YYYY
    01 <= MM <= 12
    01 <= DD <= end day of the month

  11. Yeshwanth says:

    Time is not getting printed with this code.

  12. Yeshwanth says:

    I apologise, this is working good.

Leave a Reply

Your email address will not be published. Required fields are marked *