Question

I am getting ParseException for the following code

    String dateStr = "2011-12-22 10:56:24.389362";
    String formatStr = "yyyy-MM-dd HH:mm:ss.SSSSSS";
    Date testDate = null;
    SimpleDateFormat sdf= new SimpleDateFormat(formatStr);
    sdf.setLenient(false);
    testDate = sdf.parse(dateStr);

    System.out.println("CHECK DATE " + sdf.format(testDate));

Exception in thread "main" java.text.ParseException: Unparseable date: "2011-12-22 10:56:24.389362" at java.text.DateFormat.parse(DateFormat.java:337)

If I comment out the line sdf.setLenient(false), then I see a time difference in the ouput CHECK DATE 2011-12-22 11:02:53.000362

What am I doing wrong??

Was it helpful?

Solution

'S' is for millisecond. There are 1000 (0 to 999) milliseconds in a second. 389362 is greater than 999. The extra 389000 milliseconds are getting converted to 389 seconds, or 6 minutes 29 seconds and added to the time.

OTHER TIPS

The S format specifier refers to milliseconds. When you allow lenient parsing, the last part is interpreted as 389362 milliseconds. When that's added to the date so far, the last 3 digits (actually, the value % 1000) become the actual milliseconds, and you wind up with a date about 389 seconds (~6 1/2 minutes) later than you're expecting. (With strict parsing, the parser knows that 389362 milliseconds doesn't make sense, so it throws an error.)

The simplest way around that, if you can guarantee the date will always look like that, would be to chop the last 3 digits off. (This will about half the time give you a date that's off by a millisecond. But that's better than having to write a date parser...)

Your date input for milliseconds is incorrect. It should be:-

String dateStr = "2011-12-22 10:56:24.389";

You also do not need the extra number of "S"s in the pattern. The following should suffice:

String formatStr = "yyyy-MM-dd HH:mm:ss.S";

It is clearly mentioned in the java docs for presentation type of Number:

Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.

It works when you set lenient to be true (or comment out the line which defaults it true) since you are asking the parser to be not strict about the parsing. From java docs on setLenient():-

Specify whether or not date/time parsing is to be lenient. With lenient parsing, the parser may use heuristics to interpret inputs that do not precisely match this object's format. With strict parsing, inputs must match this object's format.

S is only to be used for milliseconds. If you want microseconds, you will have to write your own parser.

Use toISOString('HH:mm:ss.S') to get milliseconds (3 digits), then complete as you need with 0.

For example:

new Date().toISOString('HH:mm:ss.S')

returns "2012-02-10T12:16:39.124Z"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top