crimson_skier
crimson_skier

Reputation: 45

SimpleDateFormat incorrectly parsing string

String s = 19.17.38.008000;
DateFormat f = new SimpleDateFormat("HH.mm.ss.SSSSSS");
Date d = f.parse(s);
system.out.println(d);

this is the code I am running it runs fine except when it prints it prints the time 19:17:46. Please someone explain this to me

As a side note:

String s = 19.17.38.008000;
DateFormat f = new SimpleDateFormat("HH.mm.ss");
Date d = f.parse(s);
system.out.println(d);

this code will print the same string correctly minus the milliseconds. Someone please tell me what I am missing here.

EDIT: Thanks for the answers I think the issue here is I was reading 38.008000 as .008 seconds but sdf is reading SSS as 8000 milliseconds which are not the same thing.

Upvotes: 4

Views: 565

Answers (3)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

java.time

In March 2014, Java 8 introduced the modern, java.time date-time API which supplanted the error-prone legacy java.util date-time API. Any new code should use the java.time API.

Solution using modern date-time API

While SimpleDateFormat considers the decimal part (the number after . point) as the number of milliseconds (e.g. 008000 ms = 8000 ms = 8 sec in the given string 19.17.38.008000) which feels confusing, the modern date-time API considers it a fraction of a second (0.008 seconds in this case) which feels intuitive.

Demo using modern date-time API:

public class Main {
    public static void main(String args[]) {
        String s = "19.17.38.008000";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH.mm.ss.SSSSSS", Locale.ENGLISH);
        LocalTime time = LocalTime.parse(s, dtf);
        System.out.println(time);
    }
}

Output:

19:17:38.008

Online Demo

SimpleDateFormat is full of many such surprises e.g., if you try using HH.mm.ss.SSS in the above code, it will throw an exception alerting you that there is something wrong. Whereas if you try using HH.mm.ss.SSS with SimpleDateFormat for your string, SimpleDateFormat will silently parse it giving you an undesirable result.

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533510

SSSSSS is still milli-seconds even if you put 6 of them. 19:17:38 + 008000 ms is 19:17:46 so it correct, if surprising.

AFAIK The java.time library in Java 8 supports micro-second (and nano-second) timestamps.

Thank you @Meno for the corrections.

Upvotes: 3

rgettman
rgettman

Reputation: 178263

The SimpleDateFormat class is interpreting 008000 as 8000 milliseconds, or 8 seconds, and adding it to the 38 seconds already interpreted.

If we had this:

String s = "19.17.38.009000";

Then we would get this output, with 9 seconds added:

Thu Jan 01 19:17:47 PST 1970

Remove the 3 extra zeroes from the end of the string. If there are 6 digits, then they look like they should represent microseconds (millionths of a second), not milliseconds (thousandths of a second).

String s = "19.17.38.008";

Output:

Thu Jan 01 19:17:38 PST 1970

Upvotes: 6

Related Questions