Reputation: 64
I am trying to convert a string to LocaleDateTime
object in Java8
as below :
DateTimeFormatter globalFormat = DateTimeFormatter.ofPattern("yyyyMMddhhmmssSS");
String input = "2019082905020425";
LocalDateTime currentDateTime = LocalDateTime.parse(input, globalFormat);
But I am getting below exception, if someone can help me with a solution on the same :
Exception in thread "main" java.time.format.DateTimeParseException: Text '2019082905020425' could not be parsed at index 0 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849) at java.time.LocalDateTime.parse(LocalDateTime.java:492)at test.main(Test.java:20)
Upvotes: 0
Views: 308
Reputation: 86276
It’s a bug in Java 8.
DateTimeFormatter globalFormat = new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmmss")
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
String input = "2019082905020425";
String adaptedInput = input + "0";
LocalDateTime currentDateTime = LocalDateTime.parse(adaptedInput, globalFormat);
System.out.println("Parsed date and time: " + currentDateTime);
Output from this snippet is (tested on jdk-1.8.0_121):
Parsed date and time: 2019-08-29T05:02:04.250
Java 8 cannot separate an integer field like ss
and a fractional fields like SS
without any separator between them. The workaround is to parse the fraction as an integer too. Your string includes 100ths of seconds, and no integer field for those is built in. So I append an extra 0
(zero) so that we’ve got milliseconds, and then use ChronoField.MILLI_OF_SECOND
for parsing.
Whether it was really a bug can maybe be debated. There never was any strict promise in the docs that it should work, but it seemed to be the expectation of many, and in any case they fixed it in Java 9.
I have made one more correction, and you will want to check whether this is the correction you want: Lowercase hh
is for hour within AM or PM from 01 through 12. If you intended this, you need to specify whether you want AM or PM. Instead I assumed that 05 was an hour of day from 00 through 23. Use uppercase HH
for parsing this.
Edit: use a regular expression? @josejuan advocates a regular expression over the above. It’s an option, and can save us of the explicit formatter completely:
String input = "2019082905020425";
String adaptedInput = input.replaceFirst(
"^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})$",
"$1-$2-$3T$4:$5:$6.$7");
LocalDateTime currentDateTime = LocalDateTime.parse(adaptedInput);
The result is the same as before. For my part I find the latter code quite a lot harder to read and maintain. Also once you migrate to Java 9 or higher, I think that the first snippet above lends itself more directly to going back to the code from which you started, which is what you want in the end. Pick the solution that you prefer.
On Java 9 and later the change from hh
to HH
is all we need for the code in the question to work fine.
hh
in a format pattern stringUpvotes: 3