javautcdstpstzoneddatetime

plusSeconds in ZonedDateTime not working as expected


Below is the logic we are trying to code.

We have startdate(SD) and enddate(ED) in UTC, we first convert startdate to PST(SD_PST) and then add difference between startdate and enddate to the PST converted startdate (SD_PST+(ED minus SD)) to obtain ED_PST(end date in PST)

Below is our partial code.

Duration duration = Duration.between(sud.getStartTime().toInstant(),
sud.getEndTime().toInstant()); // Sun Mar 12 08:00:00 PDT 2017 - [sud.getStartTime()] & Sun Mar 12 09:00:00 PDT 2017 - [sud.getEndTime()] 

ZonedDateTime ldt = ZonedDateTime.ofInstant(convertToPst(sud.getStartTime()).toInstant(),
        ZoneId.systemDefault()); // ldt now is 2017-03-12T1:00-08:00[PST8PDT]

ldt = ldt.plusSeconds(duration.getSeconds()); // ldt now is 2017-03-12T3:00-07:00[PST8PDT] , duration.getSeconds() is 3600
Date f2 = Date.from(ldt.toInstant()); // output Sun Mar 12 03:00:00 PDT 2017 

I get it that daylight saving is affecting the output, but I am unable to understand how 1 hour extra is added, my expected output is 2017-03-12T2:00-07:00[PST8PDT] (I understand that in dst -7 hours gets added).

Please help me understand the output.


Solution

  • You told in the comments that adding one hour to 2017-03-12T1:00-08:00[PST8PDT] makes it to 2017-03-12T3:00-07:00[PST8PDT]. Well, this is correct.

    This happens because Dayligh Saving Time (DST, or summer time) in PST8PDT timezone starts at the second Sunday of March, at 2 AM. When the time reaches 2 AM, the clocks shift 1 hour forward to 3 AM and the offset changes from -08:00 to -07:00.

    Take this code:

    ZonedDateTime zdt = ZonedDateTime.parse("2017-03-12T01:00-08:00[PST8PDT]");
    System.out.println(zdt); // 2017-03-12T01:00-08:00[PST8PDT]
    System.out.println(zdt.plusHours(1)); // 2017-03-12T03:00-07:00[PST8PDT]
    

    The output is:

    2017-03-12T01:00-08:00[PST8PDT]
    2017-03-12T03:00-07:00[PST8PDT]

    Note that at 1 AM the offset was -08:00. Then I added 1 hour, and the local time should have changed to 2 AM. But at 2 AM, DST starts and the clock is shifted 1 hour forward to 3 AM, and the offset changes to -07:00.

    This can become more clear if you get the corresponding Instant of each date (so you'll have those same dates in UTC):

    ZonedDateTime zdt = ZonedDateTime.parse("2017-03-12T01:00-08:00[PST8PDT]");
    System.out.println(zdt.toInstant()); // 2017-03-12T09:00:00Z
    System.out.println(zdt.plusHours(1).toInstant()); // 2017-03-12T10:00:00Z
    

    The output is:

    2017-03-12T09:00:00Z
    2017-03-12T10:00:00Z

    Note that the difference is really 1 hour.