Search code examples
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.