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?
-
wich language ? – Daniel E. May 15 '18 at 07:37
-
Have a look at this, https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html – Nyle Hassan May 15 '18 at 07:38
-
Okay, so after a lot of banging my head against a brick wall - `+3:00` is not a valid value for the formatter, it MUST have a leading zero `+03:00` :/. After I corrected for that, I ended up using `yyyy-MM-dd HH:mm:ss.n z` for `DateTimeFormatter` – MadProgrammer May 15 '18 at 08:03
-
Exactly what MadProgrammer says. You can not parse this date with java's default parsers. Other than writing a custom parser (which I don't recommend) you should programmatically add a leading 0 to your offset and parse it as a `ZonedDateTime` – Ben May 15 '18 at 08:11
-
2... or get the format correct at it's source – MadProgrammer May 15 '18 at 08:12
-
1That would obviously be the preferred way. I never understand when programs don't just simply abide by ISO 8601 for time formatting. – Ben May 15 '18 at 08:12
-
I believe that neither Java’s standard formatters nor those you can build from a format pAttern string can parse an offset with 1-digit hours such as `+3:00`. `DateTimeFormatterBuilder.appendOffset()` allows you to control the format of the offset, for example `+H:MM:ss` - hour and minute, with second if non-zero, with colon. – Ole V.V. May 15 '18 at 08:14
-
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` – Ben May 15 '18 at 08:16
-
1@Ben You are partly correct: it does not work in Java 8, but it does in Java 9 and 10. – Ole V.V. May 15 '18 at 08:21
-
@OleV.V. that's actually very good to know! Thanks! Haven't looked at that particularly in Java 9/10 yet. TIL. – Ben May 15 '18 at 08:22
-
Possible duplicate of [How to parse a date?](https://stackoverflow.com/questions/999172/how-to-parse-a-date) – AxelH May 15 '18 at 08:25
-
@AxelH I was thinking the same at first. The real problem in this question is how to parse the offset with one-digit hours, and the question you are linking to certainly doesn’t address that. It’s not really explained in this question that this is the real problem, though. – Ole V.V. May 15 '18 at 08:40
-
Well @OleV.V., the answer provide the documentation of `SimpleDateFormat` (and other provide the ISO for java.time) where we can found that this offset is not a valid offset (until java 9 based on your answer). This answer partially the "how to parse that format" since this can''t be done directly (not without some modification of the `String`). So I think this would still be a correct answer (we can't write an answer for every possible format that can be written, sometime reading the manual should be enough). But I see what you mean, this might be a borderline duplicate ;) – AxelH May 15 '18 at 08:43
2 Answers
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()
.

- 81,772
- 15
- 137
- 161
-
Thank you. Can't check it on Java 9, but on Java 8 all works fine. Really cool answer – tomasomsk May 15 '18 at 08:58
-
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? – Arvind Kumar Avinash Dec 14 '22 at 19:31
-
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 – Ole V.V. Dec 14 '22 at 20:37
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

- 81
- 10
-
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. – Ole V.V. May 15 '18 at 08:55