JDK-5055568 : SimpleDateFormat ("MM/dd/yyyy") accepts "05/21/2a00e" but not "05/2a/2004"
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 1.4.2
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-06-01
  • Updated: 2004-06-01
  • Resolved: 2004-06-01
Related Reports
Relates :  
Description
Name: js151677			Date: 06/01/2004


FULL PRODUCT VERSION :
J2SE 1.4.2_04 (on XP)
or
J2SE 1.3.1_02-b02 (on W2K)

ADDITIONAL OS VERSION INFORMATION :
Windows XP SP1
Windows 2000 SP 3

A DESCRIPTION OF THE PROBLEM :
The parse method of class SimpleDateFormat accepts inputs like "05/21/20!������$%asdf" even if lenient is set to false. The resulting year is then 20 AD. On the other hand an input like "05/2a/2004" leads to a ParseException - what I would expect in both cases.

Constructing the format with new java.text.SimpleDateFormat("MM/dd/yyyy"); leads to the same results, behaviour with using a German locale too.
 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile and run the asttached test code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
FAILED: java.text.ParseException: Unparseable date: "05/21/2a00e"

ACTUAL -
dateString 05/21/2a00e is formatted to Sun May 21 00:00:00 CEST 0002

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.text.*;
import java.util.Locale;

public class TestDFParser4WrongYear {
    
    public static void main(String [] args) {
        try {
            SimpleDateFormat format = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
            String dateString = "05/21/2a00e";
            format.setLenient(false);
            java.util.Date date = format.parse(dateString);
            System.out.println("dateString " + dateString + " is formatted to " + date.toString());
        } catch (Exception ex) {
            System.out.println("FAILED: " + ex.toString());
        }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Parsing for character input if an era designator should not be provided.
(Incident Review ID: 275821) 
======================================================================

Comments
WORK AROUND If you need to know whether the given input string is fully parsed, you can use ParsePosition. The following program demonstrates its usage. import java.text.*; import java.util.*; public class ParseTest { public static void main(String[] args) { SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); ParsePosition pp = new ParsePosition(0); String input = "05/21/2004"; Date d = sdf.parse(input, pp); System.out.println(d + ": length=" + input.length() + ", index=" + pp.getIndex()); pp = new ParsePosition(0); input = "05/21/2a00e"; d = sdf.parse(input, pp); System.out.println(d + ": length=" + input.length() + ", index=" + pp.getIndex()); } } --- output --- $ java ParseTest Fri May 21 00:00:00 PDT 2004: length=10, index=10 Sun May 21 00:00:00 PST 2: length=11, index=7 If input.length() != pp.getIndex() after parsing the input, it means that the given string didn't fully match the given pattern.
26-07-2005

EVALUATION In general, the parse methods in the Format classes stop parsing at any point where the given pattern doesn't match the given input string. The year parsing in SimpleDateFormat is defined as follows: For parsing, if the number of pattern letters is more than 2, the year is interpreted literally, regardless of the number of digits. So using the pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. Therefore, the parsing stops at 'a' of "05/21/2a00e", which is the same thing as parsing "05/21/2". On the other hand, if the given input string is "05/2a/2004", the parsing of the 'dd' part stops at 'a' and the parser continues to parse the 'yyyy' part, then fails due to no digits found at 'a'. ###@###.### 2004-06-01
01-06-2004