Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SimpleDateFormat is not parsing the milliseconds correctly

Background:

In my database table, I have two timestamps

timeStamp1 = 2011-08-23 14:57:26.662 timeStamp2 = 2011-08-23 14:57:26.9 

When I do an "ORDER BY TIMESTAMP ASC", timeStamp2 is considered as the greater timestamp(which is correct).

Requirement: I need to get the difference of these timestamps (timeStamp2 - timeStamp1)

My implementation:

public static String timeDifference(String now, String prev) {     try {         final Date currentParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(now);         final Date previousParsed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(prev);         long difference = currentParsed.getTime() - previousParsed.getTime();         return "" + difference;     } catch (ParseException e) {         return "Unknown";     } } 

The answer should have been 238ms, but the value that is returned is -653ms. I'm not sure what I'm doing wrong. Any suggestions?

like image 948
dkulkarni Avatar asked Aug 23 '11 10:08

dkulkarni


People also ask

What can I use instead of SimpleDateFormat?

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

Is SimpleDateFormat deprecated?

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

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.

What is parse in SimpleDateFormat parse do?

The parse() Method of SimpleDateFormat class is used to parse the text from a string to produce the Date. The method parses the text starting at the index given by a start position.


1 Answers

The format you are parsing and the format uses doesn't match. You expect a three digit field and are only providing one digits. It takes 9 and assumes you mean 009 when what you want is 900. Date formats are complicated and when you prove dates in a different format it may parse them differently to you.

The documentation says S means the number of milli-seconds and the number in that field is 9, so it is behaving correctly.


EDIT: This example may help

final SimpleDateFormat ss_SSS = new SimpleDateFormat("ss.SSS"); ss_SSS.setTimeZone(TimeZone.getTimeZone("GMT")); for (String text : "0.9, 0.456, 0.123456".split(", ")) {   System.out.println(text + " parsed as \"ss.SSS\" is "       + ss_SSS.parse(text).getTime() + " millis"); } 

prints

0.9 parsed as "ss.SSS" is 9 millis 0.456 parsed as "ss.SSS" is 456 millis 0.123456 parsed as "ss.SSS" is 123456 millis 
like image 67
Peter Lawrey Avatar answered Oct 08 '22 17:10

Peter Lawrey