I want to parse a date string from "2016-09-23T09:14:52.555000000" format to "23-SEP-2016" format.
Here is my code :
public class Tester {
public static void main(String[] args) {
System.out.println(displayDate("2016-09-23T09:14:52.555000000"));
System.out.println(displayDate("2016-09-28T11:56:24.552000000"));
System.out.println(displayDate("2016-09-23T09:29:12.507000000"));
System.out.println(displayDate("2016-09-26T14:55:02.702000000"));
System.out.println(displayDate("2016-09-26T09:50:24.880000000"));
System.out.println(displayDate("2016-09-26T15:20:49.397000000"));
System.out.println(displayDate("2016-09-26T15:21:21.559000000"));
}
public static String displayDate(String dateString) {
String formattedDateString = "NA";
if(dateString == null) {
return formattedDateString;
}
SimpleDateFormat oracleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.S");
SimpleDateFormat dateFormatToDisplay = new SimpleDateFormat("dd-MMM-yyyy");
try {
Date date = oracleDateFormat.parse(dateString);
formattedDateString = dateFormatToDisplay.format(date).toUpperCase();
} catch (ParseException e) {
e.printStackTrace();
}
return formattedDateString;
}
}
The problem is if I use this line
SimpleDateFormat oracleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss.S");
The output is (incorrect date values) :
29-SEP-2016 04-OCT-2016 29-SEP-2016 04-OCT-2016 06-OCT-2016 01-OCT-2016 03-OCT-2016
Whereas If use this line
SimpleDateFormat oracleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'kk:mm:ss");
The output is (correct date values)
23-SEP-2016 28-SEP-2016 23-SEP-2016 26-SEP-2016 26-SEP-2016 26-SEP-2016 26-SEP-2016
I want to know why adding "S (Millisecond)" to the format string results in incorrect values.
Even "yyyy-MM-dd'T'kk:mm:ss.SSS" returns incorrect values.
I am using this code in Android App. It works on perfectly on emulator(API 23). For some devices it displays incorrect date. Can it be related to Java version?
In Java, it's not a fraction of seconds, it's a number of milliseconds. Don't make it larger than 999.
Change your date format in Oracle to include FF3 for the fractions of seconds to yield milliseconds.
In Java, the S, or rather SSS, in your date format stands for milliseconds, which are thousands of a second. There are only thousand milliseconds in one second.
In Oracle, the date format doesn't specify milliseconds, but fractions of a second.
FF [1..9]
Fractional seconds; no radix character is printed. Use the X format element to add the radix character. Use the numbers 1 to 9 after FF to specify the number of digits in the fractional second portion of the datetime value returned. If you do not specify a digit, then Oracle Database uses the precision specified for the datetime datatype or the datatype's default precision. Valid in timestamp and interval formats, but not in DATE formats.
In Java, if you need a third of a second, you can't get more precise than 333 milliseconds. In Oracle however, you could express it as 333333 microseconds, or perhaps even 333333333 nanoseconds.
Oracle lets you specify the number of decimal digits you want, but if you don't, you get as much as the precision for the type allows. In your case, that seems to be 9.
Then your date format in Java interprets that as a number of milliseconds. Millions and billions of them. These are added to the rest of your date. Since there are only 86,400,000 milliseconds in a day, anything over that is another day added to your date.
Let's take a look at your first test case, 2016-09-23T09:14:52.555000000.
555000000 milliseconds = 555000 seconds ≈ 154 hours ≈ 6 days and 10 hours.
Adding 6 days and 10 hours to the rest of your date, which is 2016-09-23 09:14:52, should get you to about 2016-09-29 19:00 and a bit. Change your output format (dateFormatToDisplay) to include the hours and you'll see what's happening.
Your Java date format expects no more than 3 digits for the milliseconds. Specify the number of fractional digits in Oracle. FF uses the maximal precision available for the type, FF3 only outputs 3 fractional digits — milliseconds.
If you can't alter the date format used in Oracle, trim it down to three decimal digits in Java. Note that anything less than 3 digits should be padded with zeroes to a length of three digits; 34.12 is interpreted as 34 seconds and 12 milliseconds, while you might be looking for 120 milliseconds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With