Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8262288

ChronoUnit.DAYS.between with ZonedDateTime off by one when diff spans leap month

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Not an Issue
    • Affects Version/s: 11.0.10
    • Fix Version/s: None
    • Component/s: core-libs
    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      ADDITIONAL SYSTEM INFORMATION :
      OSX 10.15, Windows 10, CentOs 7/8
      Java 8 and 11 tested

      A DESCRIPTION OF THE PROBLEM :
      When getting the difference between two zoned dates (UTC) if now is in February of a leap year and the other date is beyond February. The between returns an incorrect value. One less than expected

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));

              ZonedDateTime constructedNow = ZonedDateTime
                      .of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
                              .getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
                              .getSecond(), 0, ZoneId.of("UTC"));
              ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);

              System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
              System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
              System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));

              System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
                      .between(systemCurrent, plus25days));
              System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Days between should be 25 and hours between should be 600
      ACTUAL -
      onstructed Now: 2021-02-23T19:42:49Z[UTC] Plus 25: 2021-03-20T19:42:49Z[UTC]
      Days between: 25
      hours between: 600
      System Current: 2021-02-23T19:42:49.576340Z[UTC]
      Days Between 24 <-- off by 1 (day)
      hours between: 599 <-- off by 1 (hour)

      ---------- BEGIN SOURCE ----------
      import java.time.*;
      import java.time.temporal.ChronoUnit;

      class Scratch {
          public static void main(String[] args) {
              ZonedDateTime systemCurrent = ZonedDateTime.now(ZoneId.of("UTC"));

              ZonedDateTime constructedNow = ZonedDateTime
                      .of(systemCurrent.getYear(), systemCurrent.getMonthValue(), systemCurrent
                              .getDayOfMonth(), systemCurrent.getHour(), systemCurrent.getMinute(), systemCurrent
                              .getSecond(), 0, ZoneId.of("UTC"));
              ZonedDateTime plus25days = constructedNow.plus(25, ChronoUnit.DAYS);

              System.out.println("Constructed Now: " + constructedNow + " Plus 25: " + plus25days);
              System.out.println("Days between: " + ChronoUnit.DAYS.between(constructedNow, plus25days));
              System.out.println(("hours between: " + ChronoUnit.HOURS.between(constructedNow, plus25days)));

              System.out.println("System Current: " + systemCurrent + "\nDays Between " + ChronoUnit.DAYS
                      .between(systemCurrent, plus25days));
              System.out.println(("hours between: " + ChronoUnit.HOURS.between(systemCurrent, plus25days)));
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Strangely if you set the nanoOfSecond of the constructedNow to the value of systemCurrent.getNano()
      then ChronoUnit.HOURS.between(systemCurrent, plus25days) returns the correct value.
      **** calling a the getter on ZonedDateTime in the context of a ZonedDateTime constructor fixes the issue ****

        Attachments

          Activity

            People

            Assignee:
            tongwan Andrew Wang
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: