Issue creating ZonedDateTime instance based on LocalDateTime
Issue creating ZonedDateTime instance based on LocalDateTime
I'm seeing some behavior I can't explain, hoping somebody can point me in the right direction.
I'm first creating a LocalDateTime instance, then getting to ZonedDateTime by applying the "Europe/London" time zone to the LocalDateTime and then use a DateTimeFormatter to print to output. I would expect to see the exact same time as specified in the LocalDateTime instance, but in below example the output for zonedDateTimeBeforeDST_Original is showing one hour later than what I would expect.
So, in short: why does 01:55 in my LocalDateTime become 02:55 for the ZonedDateTime?
FYI, didn't see this behavior for other time zones. The London one seems to be a special case.
//init date pattern
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
final DateTimeFormatter formatterOut = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss XXX");
LocalDateTime localDateTimeBeforeDST = LocalDateTime.parse("2018-03-25 01:55:00", formatter); //testing with time 5 minutes before DST switch or after
System.out.println("LocalDateTime: " + localDateTimeBeforeDST.format(formatter));
System.out.println();
String originalZone = "Europe/London";
ZoneId originalZoneId = ZoneId.of(originalZone);
ZoneId utcZoneId = ZoneId.of("Etc/UTC");
ZoneId localZoneId = ZoneId.of("Europe/London");
ZoneId localZoneId_2 = ZoneId.of("Europe/Brussels");
ZonedDateTime zonedDateTimeBeforeDST_Original = localDateTimeBeforeDST.atZone(originalZoneId);
ZonedDateTime zonedDateTimeBeforeDST_UTC = zonedDateTimeBeforeDST_Original.withZoneSameInstant(utcZoneId);
ZonedDateTime zonedDateTimeBeforeDST_1 = zonedDateTimeBeforeDST_UTC.withZoneSameInstant(localZoneId);
ZonedDateTime zonedDateTimeBeforeDST_2 = zonedDateTimeBeforeDST_UTC.withZoneSameInstant(localZoneId_2);
System.out.println("Instant: " + zonedDateTimeBeforeDST_Original.toEpochSecond());
System.out.println();
System.out.println("ZonedDateTime (" + originalZone + "): " + zonedDateTimeBeforeDST_Original.format(formatterOut));
System.out.println("ZonedDateTime (Etc/UTC): " + zonedDateTimeBeforeDST_UTC.format(formatterOut));
System.out.println("ZonedDateTime (Europe/London): " + zonedDateTimeBeforeDST_1.format(formatterOut));
System.out.println("ZonedDateTime (Europe/Brussels): " + zonedDateTimeBeforeDST_2.format(formatterOut));
System.out.println();
zonedDateTimeBeforeDST_Original = zonedDateTimeBeforeDST_Original.plus(10, ChronoUnit.MINUTES);
zonedDateTimeBeforeDST_UTC = zonedDateTimeBeforeDST_Original.withZoneSameInstant(utcZoneId);
zonedDateTimeBeforeDST_1 = zonedDateTimeBeforeDST_UTC.withZoneSameInstant(localZoneId);
zonedDateTimeBeforeDST_2 = zonedDateTimeBeforeDST_UTC.withZoneSameInstant(localZoneId_2);
System.out.println("ZonedDateTime (DST) (" + originalZone + "): " + zonedDateTimeBeforeDST_Original.format(formatterOut));
System.out.println("ZonedDateTime (DST) (Etc/UTC): " + zonedDateTimeBeforeDST_UTC.format(formatterOut));
System.out.println("ZonedDateTime (DST) (Europe/London): " + zonedDateTimeBeforeDST_1.format(formatterOut));
System.out.println("ZonedDateTime (DST) (Europe/Brussels): " + zonedDateTimeBeforeDST_2.format(formatterOut));
Output:
LocalDateTime: 2018-03-25 01:55:00
Instant: 1521942900
ZonedDateTime (Europe/London): 2018-03-25 02:55:00 +01:00
ZonedDateTime (Etc/UTC): 2018-03-25 01:55:00 Z
ZonedDateTime (Europe/London): 2018-03-25 02:55:00 +01:00
ZonedDateTime (Europe/Brussels): 2018-03-25 03:55:00 +02:00
ZonedDateTime (DST) (Europe/London): 2018-03-25 03:05:00 +01:00
ZonedDateTime (DST) (Etc/UTC): 2018-03-25 02:05:00 Z
ZonedDateTime (DST) (Europe/London): 2018-03-25 03:05:00 +01:00
ZonedDateTime (DST) (Europe/Brussels): 2018-03-25 04:05:00 +02:00
1 Answer
1
It’s a summer time (DST) issue. When summer time began in the UK and the clocks were turned forward from 1 to 2, there was no 2018-03-25 01:55:00. ZonedDateTime
doesn’t give you a non-existing time, so it chose an existing one instead.
ZonedDateTime
Exactly which time it chooses is specified in the documentation of LocalDateTime.atZone
:
LocalDateTime.atZone
In the case of a gap, where clocks jump forward, there is no valid
offset. Instead, the local date-time is adjusted to be later by the
length of the gap. For a typical one hour daylight savings change, the
local date-time will be moved one hour later into the offset typically
corresponding to "summer".
The same thing happens in other time zones that use summer time, of course. Only each time zone has its own transition time which typically does not coincide with Sunday, March 25 2018 at 01:00.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Comments
Post a Comment