I have several code snippets. Some of them works and some not but I don't understand why.
DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"); //(7 positions after last dor)
TIME_FORMATTER.parse("2021-06-22T18:27:03.5577Z")//Broken 4
TIME_FORMATTER.parse("2021-06-22T18:27:03.55770Z")//Broken 5
TIME_FORMATTER.parse("2021-06-22T18:27:03.557700Z")//Working 6
TIME_FORMATTER.parse("2021-06-22T18:27:03.5577000Z")//Working 7
TIME_FORMATTER.parse("2021-06-22T18:27:03.55770000Z")//Broken 8
See this code work, or not work, when running live at IdeOne.com.
Why it works for both: 6 and 7 digits after the decimal separator, but not 4, 5, or 8 digits?
How to create a formatter which would work for 4, 5, 6, 7, or 8 digits?
You asked:
How to create Format which will work for 4,5,6,7 numbers after point ?
Use the predefined formatter, DateTimeFormatter.ISO_INSTANT
.
DateTimeFormatter.ISO_INSTANT.parse("2021-06-22T18:27:03.5577Z")
Z
Never put quote-marks around Z in your formatting pattern. That letter is carries crucial information, and is not mere decoration. That letter indicates an offset from UTC of zero hours-minutes-seconds. Your single-quote-marks around Z
indicate that letter should be expected and then ignored.
When ignoring the offset, you are left with a date and time only. A date and time are not enough to represent a moment. We cannot know if your input meant 6:30 PM in Tokyo, 6:30 PM in Toulouse, or 6:30 PM in Toledo — all very different moments several hours apart.
For a point on the timeline we require a third piece, the context of an offset or a time zone.
java.time.Instant.parse
Your input text complies with the ISO 8601 standard used by default in java.time. So no need to specify a formatting pattern.
Simply parse the input as an Instant
object. The Instant
represents a moment as seen in UTC, with an offset of zero.
The Instant.parse
method uses the predefined formatter in the constant DateTimeFormatter.ISO_INSTANT
.
Instant instant4 = Instant.parse("2021-06-22T18:27:03.5577Z") ;
Instant instant5 = Instant.parse("2021-06-22T18:27:03.55770Z") ;
Instant instant6 = Instant.parse("2021-06-22T18:27:03.557700Z") ;
Instant instant7 = Instant.parse("2021-06-22T18:27:03.5577000Z") ;
Instant instant8 = Instant.parse("2021-06-22T18:27:03.55770000Z") ;
See this code run live at IdeOne.com.
2021-06-22T18:27:03.557700Z
2021-06-22T18:27:03.557700Z
2021-06-22T18:27:03.557700Z
2021-06-22T18:27:03.557700Z
If curious as to how ISO_INSTANT
is written in OpenJDK, see the source code.