I am migrating an application from jdk 8 to 11 and I can see ZonedDateTime change is behavior about daylight saving time. JDK8
ZonedDateTime parse = ZonedDateTime.parse("2037-05-10T19:15:00.000+01:00[Europe/Paris]");
System.out.println(parse);
output: 2037-05-10T19:15+02:00[Europe/Paris]
JDK11/12
ZonedDateTime parse = ZonedDateTime.parse("2037-05-10T19:15:00.000+01:00[Europe/Paris]");
System.out.println(parse);
2037-05-10T20:15+02:00[Europe/Paris]
Can someone explain to me why did they change this behavior ?
Best regards,
It’s a known bug in Java 8: JDK-8066982
I believe that what you are experiencing in Java 8 is really this bug: ZonedDateTime.parse() returns wrong ZoneOffset around DST fall transition. The bug title doesn’t tell the whole story. The real issue is that in Java 8
DateTimeFormatter.ISO_ZONED_DATE_TIME
(which is implicitly used by the one-argZonedDateTime.parse
that you use) ignores the offset if a time zone ID is included in the parsed string. This in combination with a time zone database that disagrees with your string about the offset used in Paris in October 2037 causes a moment in time to be parsed that conflicts with the offset in the string.The bug is fixed in Java 9. So in Java 9, 10 and 11, since the same disagreement about offset is still there, the moment parsed is based on the offset of the string. It is then converted to the time zone from the string using the rules from the time zone database. This causes the offset to be changed from +01:00 to +02:00 and the hour of day correspondingly from 19:15 to 20:15. I agree with Java 9+ that this is the correct behaviour.
Don’t use ZonedDateTime for far-future dates
Your problem is also partly caused by using
ZonedDateTime
for a future date. This is only recommended for the very near future where we assume that no zone rules are changed. For a date and time in 2037, you should either use anInstant
if you know the moment in time, or aLocalDateTime
if you know just the date and time of day. Only when the time draws near and you trust that your Java installation has got the last time zone updates, convert to aZonedDateTime
.As has been discussed in the comments, we probably don’t know the correct UTC offset for Paris in October 2037 yet. It seems that EU is likely to abandon summer time (DST) from 2021, and as far as I know, the French politicians have not yet decided what the time will be in France after that.
What if we wanted the time of day from the string?
To get the time from the string (19:15), parse into a
LocalDateTime
:Output is (run on Java 11):
In case you wanted the full Java 8 behaviour on a later Java version — as I mentioned, it’s not recommended, you shouldn’t use
ZonedDateTime
here: