سؤال

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.

هل كانت مفيدة؟

المحلول 2

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.

نصائح أخرى

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

SimpleDateFormat does not parse beyond milliseconds precision. Also, look at the following description from the documentation (emphasis mine):

Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.

Thus, even though your pattern has six S's, SimpleDateFormat uses only the first three of them i.e.

HH.mm.ss.SSS

In other words, for your string, SimpleDateFormat will give you the same wrong result whether you use HH.mm.ss.SSS or HH.mm.ss.SSSSSS. SimpleDateFormat is full of many such surprises. In order to fix the problem while using SimpleDateFormat, you need to drop three 0s from the end of your string i.e. if you parse 19.17.38.008, SimpleDateFormat will give your the desired result.

Thus, the legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) is not only outdated but also error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API*.

Demo using modern date-time API:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

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

Note that if you try using HH.mm.ss.SSS, for your string, with java.time API, it will throw an exception alerting you that there is something wrong whereas SimpleDateFormat silently parses your string giving you an undesirable result.

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


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top