If you want to parse all valid formats of offsets (Z
, ±hh:mm
, ±hhmm
and ±hh
), one alternative is to use a java.time.format.DateTimeFormatterBuilder
with optional patterns (unfortunatelly, it seems that there's no single pattern letter to match them all):
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// date/time
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
// offset (hh:mm - "+00:00" when it's zero)
.optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd()
// offset (hhmm - "+0000" when it's zero)
.optionalStart().appendOffset("+HHMM", "+0000").optionalEnd()
// offset (hh - "Z" when it's zero)
.optionalStart().appendOffset("+HH", "Z").optionalEnd()
// create formatter
.toFormatter();
System.out.println(OffsetDateTime.parse("2022-03-17T23:00:00.000+0000", formatter));
System.out.println(OffsetDateTime.parse("2022-03-17T23:00:00.000+00", formatter));
System.out.println(OffsetDateTime.parse("2022-03-17T23:00:00.000+00:00", formatter));
System.out.println(OffsetDateTime.parse("2022-03-17T23:00:00.000Z", formatter));
All the four cases above will parse it to 2022-03-17T23:00Z
.
You can also define a single string pattern if you want, using []
to delimiter the optional sections:
// formatter with all possible offset patterns
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS[xxx][xx][X]");
This formatter also works for all cases, just like the previous formatter above. Check the javadoc to get more details about each pattern.
Notes:
.SSS
). On the other hand, ISO_LOCAL_DATE_TIME
is more flexible: the seconds and nanoseconds are optional, and it also accepts from 0 to 9 digits after the decimal point. Choose the one that works best for your input data.You don't need to write a complex regex - you can build a DateTimeFormatter
that will work with that format easily:
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX", Locale.ROOT);
OffsetDateTime odt = OffsetDateTime.parse(input, formatter);
That will also accept "Z" instead of "0000". It will not accept "+00:00" (with the colon or similar. That's surprising given the documentation, but if your value always has the UTC offset without the colon, it should be okay.
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