I am trying to parse: 2014-05-02-10.45.05.993280-5:00
where the -5:00
is the offset from UTC. Using a java.time DateTimeFormatter
in Java 8.
For the first bit I have the following: yyyy-MM-dd-HH.mm.ss.SSSSSS
however, I can't figure out what the pattern should be to parse the offset also.
If I had the offset with 4 digits (-05:00) I could use: yyyy-MM-dd-HH.mm.ss.SSSSSSxxx
, but this doesn't work for 3 digits.
Any ideas?
The LocalDateTime API gives the possibility to add the TimeZone Name by using the key "z" in the formatter.
DateTimeFormatter is used as a Formatter for printing and parsing date-time objects. DateTimeFormatterBuilder allows a DateTimeFormatter to be created. It is used for constructing formatters which are then used to print or parse.
The OffsetTime class, in effect, combines the LocalTime class with the ZoneOffset class. It is used to represent time (hour, minute, second, nanosecond) with an offset from Greenwich/UTC time (+/-hours:minutes, such as +06:00 or -08:00).
A formatter created from a pattern can be used as many times as necessary, it is immutable and is thread-safe. The count of pattern letters determines the format.
Use capital letter X instead of x, hence XXX. The difference is that big X can recognize the input letter "Z" as UTC-Offset +00:00 while small pattern letter X cannot.
Suggested pattern:
yyyy-MM-dd-HH.mm.ss.SSSSSSXXX
Please be also aware of following JDK-bug:
java.time.format.DateTimeFormatter cannot parse an offset with single digit hour
UPDATE:
I have now tested the described workaround in the bug-log.
String input = "2014-05-02-10.45.05.993280-5:00"; DateTimeFormatter f = new DateTimeFormatterBuilder() .appendPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS") .parseLenient() .appendOffset("+HH:MM", "Z") .toFormatter(); System.out.println(f.parse(input, ZonedDateTime::from));
But it throws an exception:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2014-05-02-10.45.05.993280-5:00' could not be parsed at index 26 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849) at HelloWorld.main(HelloWorld.java:16)
So lenient parsing does not help either. So there are now only three options left for you:
Use workaround suggested by bug reporter: [...] workaround is to parse the date/time separately, use a hand coded parser for the offset and combine the LocalDateTime with the hand parsed offset. Not an easy work around.
Try your own specialized string preprocessing. If you have a fixed format then you can try to insert the zero-digit at position 26 (if the total input length is one digit too small).
Or you use an external library which can do this. My library Time4J (v4.0) can do that if you are willing to add an extra dependency. See this code:
String input = "2014-05-02-10.45.05.993280-5:00"; ZonalDateTime zdt = ZonalDateTime.parse( input, Moment.localFormatter("yyyy-MM-dd-HH.mm.ss.SSSSSSXXX", PatternType.CLDR)); System.out.println(zdt); // 2014-05-02T10:45:05,993280UTC-05:00 ZonedDateTime result = zdt.toTemporalAccessor();
Update: According to JDK-bug-status, the bug has been fixed for Java-9, but a backport for Java-8 does not seem to be available though.
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