4

I need to parse date in Java. I have String value 2018-05-15 09:32:51.550082 +3:00 and I need to parse it into date-time. I tried to parse to ZonedDateTime, but I got an error at index 10. Tried to parse with DateTimeFormatter parser 'yyyy-MM-dd HH:mm:ss.SSSSSS Z' and got error at index 26. Apparently my UTC offset of +3:00 cannot be parsed. How can I do this?

13
  • wich language ? Commented May 15, 2018 at 7:37
  • 2
    ... or get the format correct at it's source Commented May 15, 2018 at 8:12
  • 1
    That would obviously be the preferred way. I never understand when programs don't just simply abide by ISO 8601 for time formatting. Commented May 15, 2018 at 8:12
  • 1
    @OleV.V. good idea but sadly the pattern does not allow H only, it has to be HH or you run into an IllegalArgumentException Commented May 15, 2018 at 8:16
  • 1
    @Ben You are partly correct: it does not work in Java 8, but it does in Java 9 and 10. Commented May 15, 2018 at 8:21

2 Answers 2

7

Java 9 and later allows:

    String dateTimeString = "2018-05-15 09:32:51.550082 +3:00";
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd HH:mm:ss.SSSSSS ")
            .appendOffset("+H:MM:ss", "+0:00")
            .toFormatter();
    OffsetDateTime dateTime = OffsetDateTime.parse(dateTimeString, formatter);
    System.out.println(dateTime);

Output:

2018-05-15T09:32:51.550082+03:00

For Java 8 or the ThreeTen Backport you will probably have to prepare your date-time string before parsing it:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS XXX");
    dateTimeString 
            = dateTimeString.replaceFirst("([+-])(\\d(?::\\d\\d){0,2})$", "$10$2");

The rest is as before and gives the same result. The replaceFirst call inserts a 0 between the + and 3:00, but only if the hours were only one digit. The regular expression is hard to read, so you will prefer the Java 9 solution.

As already discussed in the comments the hard part is the offset of +3:00. Java’s built-in formatters and the format pattern letters you can use for specifying your own format all require two-digit hours in the offset. The DateTimeFormatterBuilder.appendOffset method that I am using allows a limited number of formats to be specified; 9 different formats in Java 8; 22 in Java 9. Link: Documentation of appendOffset().

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. Can't check it on Java 9, but on Java 8 all works fine. Really cool answer
Good answer! I typically use +H:mm:ss i.e. m instead of M. However, M also works correctly. Maybe I haven't spent enough time looking into the documentation and if you have used it knowingly, can you please point me to the documentation?
In this case upper case letter means mandatory and lower case means optional. I could not be sure, but since 00 minutes were given in the example, I assumed they were mandatory and used upper case MM. Will add link, thanks for asking. @ArvindKumarAvinash
0

Comment from MadProgrammer is really helpful. Thanks, man. At first I add 0 before 3 in timezone and my string had became '2018-05-15 09:32:51.550082 +03:00' and then I use DateTimeFormatter 'yyyy-MM-dd HH:mm:ss.n z' and all works now. Thanks to all

1 Comment

That gives me 2018-05-15T09:32:51.000550082+03:00. The decimals on the second are three positions too far to the right. Otherwise fine. And in any case thanks for sharing your solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.