Tuesday, July 2, 2013

Parsing text to create Date in Java

Recently came across a bug where the incorrect date text is getting parsed even though a valid format was specified. Java.text.SimpleDateFormat.java is used for parsing the date text.  

For example: the specified format is yyyyMMdd and the text given as input to parse is of 10252012. In such cases we expect java to through an error saying the specified text is not in expected/specified format.

After going through the java doc, found the mistake that I was doing.  The parser used in SimpleDateFormat.java may use heuristics to interpret inputs that do not precisely match specified format and if the given text fits into one of those formats then the respective Date object is created. To avoid parser to use heuristics and strictly use the format specified by user one need to call setLenient(false) method available in the SimpleDateFormat.java. By default parser is lenient (meaning set to true).


Sample Code:
------------------------------------------------------------------------------------------------------------
            String dateFormat = "yyyyMMdd";
            String correctDateText = "20121025";
            String inCorrectDateText = "10252012";
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
           
            Date correctdateObj = sdf.parse(correctDateText);
            System.out.println(" Date :" +correctdateObj);
           
            Date inCorrectDateObj = sdf.parse(inCorrectDateText);
            System.out.println(" Date :" +inCorrectDateObj);
           
            sdf.setLenient(false);
           
            correctdateObj = sdf.parse(correctDateText);
            System.out.println(" Date :" +correctdateObj);
           
            inCorrectDateObj = sdf.parse(inCorrectDateText);
            System.out.println(" Date :" +inCorrectDateObj);
------------------------------------------------------------------------------------------------------------
Output
------------------------------------------------------------------------------------------------------------
Date :Thu Oct 25 00:00:00 IST 2012
Date :Fri Aug 12 00:00:00 IST 1026
Date :Thu Oct 25 00:00:00 IST 2012
Exception in thread "main" java.text.ParseException: Unparseable date: "10252012"
       at java.text.DateFormat.parse(Unknown Source)
       at amdocs.ar.test.DummyTests.main(DummyTests.java:27)
------------------------------------------------------------------------------------------------------------

To continue further this is true for other cases as well.  Consider a leap year example, year 2011 is not a leap year and a date of 29th Feb 2011 should result in error if passed as input to SimpleDateFormat parser but that is not the case. It consider 29th Feb 2011 as 1st Mar 2011 and this may not be the expected business case in all scenarios. Setting the lenient to false stops this behavior.


Sample Code:
------------------------------------------------------------------------------------------------------------
            String dateFormat = "yyyyMMdd";
           
            String inCorrectDateText = "20110229";
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
           
            
            Date inCorrectDateObj = sdf.parse(inCorrectDateText);
            System.out.println(" Date :" +inCorrectDateObj);           
            sdf.setLenient(false);
                               
            inCorrectDateObj = sdf.parse(inCorrectDateText);
            System.out.println(" Date :" +inCorrectDateObj);
------------------------------------------------------------------------------------------------------------
Output
------------------------------------------------------------------------------------------------------------
Date :Tue Mar 01 00:00:00 IST 2011
Exception in thread "main" java.text.ParseException: Unparseable date: "20110229"
at java.text.DateFormat.parse(DateFormat.java:357)
at amdocs.test.Test.main(Test.java:19)
------------------------------------------------------------------------------------------------------------

No comments:

Post a Comment