Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat cannot parse milliseconds with more than 4 digits

I want to parse a timestamp, like this - "2016-03-16 01:14:21.6739". But when I use the SimpleDateFormat to parse it, I find that it outputs an incorrect parsed value. It will covert 6739 milliseconds to 6 seconds with 739 millseconds left. It converted the date to this format - Wed Mar 16 01:14:27 PDT 2016. Why the seconds part has changed from 21 seconds to 27 seconds(an addition of 6 seconds?). The following is my code snippet:

final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
String parsedate="2016-03-16 01:14:21.6739";
try {
    Date outputdate = sf.parse(parsedate);
    String newdate = outputdate.toString();  //==output date is: Wed Mar 16 01:14:27 PDT 2016 
    System.out.println(newdate);
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
like image 820
Alter Hu Avatar asked Mar 17 '16 08:03

Alter Hu


People also ask

How many digits are in a millisecond?

milliseconds are always three digit #54.

Is SimpleDateFormat deprecated?

Class SimpleDateFormat. Deprecated. A class for parsing and formatting dates with a given pattern, compatible with the Java 6 API.

What can I use instead of SimpleDateFormat?

DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.

Why is SimpleDateFormat not thread-safe?

2.2.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. So SimpleDateFormat instances are not thread-safe, and we should use them carefully in concurrent environments.


2 Answers

If you have to get string as final output why not use format instead of parse

        final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        sf.setTimeZone(TimeZone.getTimeZone("UTC")); 
        Date curDate = new Date();

        String outputdate = sf.format(curDate);
        // 2016-03-17 09:45:28.658+0000
        System.out.println(outputdate);

        Date strToDate = new Date();
        try {
            strToDate = sf.parse(outputdate);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //Thu Mar 17 17:11:30 MYT 2016
        System.out.println(strToDate);

and instead of "yyyy-MM-dd HH:mm:ss.SSSS" use "yyyy-MM-dd HH:mm:ss.SSSZ" check it here https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

"yyyy-MM-dd'T'HH:mm:ss.SSSZ"    2001-07-04T12:08:56.235-0700
like image 108
Raunak Kathuria Avatar answered Oct 27 '22 05:10

Raunak Kathuria


It seems that is not possible to use SimpleDateFormat to express times with a finer grain than the millisecond. What is happening is that as you put 6739, Java understands it as 6739 milliseconds i.e. 6 seconds and 739 milliseconds hence the 6 seconds difference observed.

Check these ones, it is explained quite well: String-Date conversion with nanoseconds Java date parsing with microsecond or nanosecond accuracy

like image 42
Bruno Piqueras Avatar answered Oct 27 '22 05:10

Bruno Piqueras