36

When I do this

String datum = "20130419233512"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin")); OffsetDateTime datetime = OffsetDateTime.parse(datum, formatter); 

I get the following exception:

 java.time.format.DateTimeParseException: Text '20130419233512' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1366407312},ISO,Europe/Berlin resolved to 2013-04-19T23:35:12 of type java.time.format.Parsed 

How can I parse my datetime string so that it is interpreted as always being from the timezone "Europe/Berlin" ?

1

2 Answers 2

36

The problem is that there is a difference between what a ZoneId is and a ZoneOffset is. To create a OffsetDateTime, you need an zone offset. But there is no one-to-one mapping between a ZoneId and a ZoneOffset because it actually depends on the current daylight saving time. For the same ZoneId like "Europe/Berlin", there is one offset for summer and a different offset for winter.

For this case, it would be easier to use a ZonedDateTime instead of an OffsetDateTime. During parsing, the ZonedDateTime will correctly be set to the "Europe/Berlin" zone id and the offset will also be set according to the daylight saving time in effect for the date to parse:

public static void main(String[] args) { String datum = "20130419233512"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("Europe/Berlin")); ZonedDateTime datetime = ZonedDateTime.parse(datum, formatter); System.out.println(datetime.getZone()); // prints "Europe/Berlin" System.out.println(datetime.getOffset()); // prints "+02:00" (for this time of year) } 

Note that if you really want an OffsetDateTime, you can use ZonedDateTime.toOffsetDateTime() to convert a ZonedDateTime into an OffsetDateTime.

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

4 Comments

I like that you do this in one step, rather than in two like I showed. I'll leave my answer since both will work, but I'd recommend yours for the green checkmark. :)
Since I need OffsetDateTime I use now OffsetDateTime datetime = ZonedDateTime.parse(datum, formatter).toOffsetDateTime(); .
@asmaier Yep, that's what I commented also. You can use that to convert to an OffsetDateTime.
The documentation of that method says "The zone ID is ignored". What does that mean exactly?
15

There's no offset in your source data, and thus OffsetDateTime is not the correct type to use during parsing.

Instead, use a LocalDateTime, since that is the type that most closely resembles the data you have. Then use atZone to assign it a time zone, and if you still need an OffsetDateTime, you can call toOffsetDateTime from there.

String datum = "20130419233512"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); LocalDateTime datetime = LocalDateTime.parse(datum, formatter); ZonedDateTime zoned = datetime.atZone(ZoneId.of("Europe/Berlin")); OffsetDateTime result = zoned.toOffsetDateTime(); 

2 Comments

Thanks. That works for me. I somehow assumed the OffsetDateTime.parse() method would do these steps internally for me.
This one works perfectly, I somehow thought the same thing as OP. This looks neat!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.