Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.text.ParseException: Unparseable date: yyyy-MM-dd HH:mm:ss.SSSSSS

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??

like image 478
Praneeth Avatar asked Dec 22 '11 17:12

Praneeth


4 Answers

'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.

like image 136
Skip Head Avatar answered Sep 21 '22 17:09

Skip Head


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

like image 35
cHao Avatar answered Sep 19 '22 17:09

cHao


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.

like image 38
CoolBeans Avatar answered Sep 23 '22 17:09

CoolBeans


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

like image 35
Igor Avatar answered Sep 21 '22 17:09

Igor