Home > Software engineering >  Daylight Saving Time - Java
Daylight Saving Time - Java

Time:04-02

I have the following timezone "2021-06-06T06:00 01:00[Europe/London]"

When I call toInstant() on that timezone, I get "2021-06-06T05:00". Clocks go forward, so why is it returning 5 am? I am trying to get 7 am rather than 5 am.

CodePudding user response:

This is simply how timezone offsets are defined, check for example Wikipedia.

A timezone designator of 01:00 means the given time is in a timezone 1 hour ahead of UTC, meaning the same time in UTC is the given time minus 1 hour.

Therefore 2021-06-06T06:00 01:00 is the same moment as 2021-06-06T05:00 00:00, without daylight saving time it would be 1 hour earlier in the day.

CodePudding user response:

Code 1

TimeZone tzLondon = TimeZone.getTimeZone("Europe/London");
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 6, 6, 0, 0, 0, tzLondon.toZoneId());
Instant instant = zonedDateTime.toInstant();
System.out.println("  zoned: "   zonedDateTime);
System.out.println("instant: "   instant);

Output 1

  zoned: 2021-06-06T06:00 01:00[Europe/London]
instant: 2021-06-06T05:00:00Z

The zoned output is based on the timezone Europe/London, which is GMT 1 during Daylight Saving Time (DST), which is why it seems to be 1 hour after the instant output (05:00 1 hour = 06:00). But both outputs represent the same point in time, just in different formats.

Usually in Java, you don't deal with DST calculation directly, because Java does it for you. You can see this, when you take the ZonedDateTime from above, and add a few months.

Code 2

ZonedDateTime zonedDateTimeAFewMonthsLater = zonedDateTime.plusMonths(5);
Instant instantAFewMonthsLater = zonedDateTimeAFewMonthsLater.toInstant();
System.out.println("A few months later   (zoned): "   zonedDateTimeAFewMonthsLater);
System.out.println("A few months later (instant): "   instantAFewMonthsLater);

Output 2

A few months later   (zoned): 2021-11-06T06:00Z[Europe/London]
A few months later (instant): 2021-11-06T06:00:00Z

But if you really really want to patch your ZonedDateTime from 06:00 to 07:00, depending on its DST properties, you can do this. But it's dirty.

Code 3

Duration dstDuration = zonedDateTime.getZone().getRules().getDaylightSavings(instant);
ZonedDateTime dstPatchedZonedDateTime = zonedDateTime.plus(dstDuration);
System.out.println("DST patched: "   dstPatchedZonedDateTime);

Output 3

DST patched: 2021-06-06T07:00 01:00[Europe/London]
  • Related