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

ZonedDateTime compareTo returns invalid value when comparing now() against now()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • tbd
    • 8u45, 9
    • core-libs
    • x86_64
    • linux_ubuntu

      FULL PRODUCT VERSION :
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      ubuntu 14.04 LTS 64 bit

      A DESCRIPTION OF THE PROBLEM :
      I am trying to compare two ZonedDateTimes obtained from ZonedDateTime.now() using ZonedDateTime's compareTo function. When get two two ZonedDateTimes in quick succession, and compare them, compare to returns a value other than 1, 0, or -1.

      Here is the sample code I ran.

      public class Main {

          private static final ZoneId ET = ZoneId.of("America/New_York");

          public static void main(String[] args) {
              ZonedDateTime ts1 = ZonedDateTime.now(ET);
              ZonedDateTime ts2 = ZonedDateTime.now(ET);
              System.out.println(ts1);
              System.out.println(ts2);
              System.out.println(ts1.compareTo(ts2));
              System.out.println(ts1.equals(ts2));
          }
      }

      The output I receive is

      2015-05-08T13:13:04.698-04:00[America/New_York]
      2015-05-08T13:13:04.789-04:00[America/New_York]
      -91000000
      false

      If I add at least a second to the to one of the ZonedDateTimes, the comparison works as seen here

      public class Main {

          private static final ZoneId ET = ZoneId.of("America/New_York");

          public static void main(String[] args) {
              ZonedDateTime ts1 = ZonedDateTime.now(ET);
              ZonedDateTime ts2 = ZonedDateTime.now(ET).plusSeconds(1);
              System.out.println(ts1);
              System.out.println(ts2);
              System.out.println(ts1.compareTo(ts2));
              System.out.println(ts1.equals(ts2));
          }
      }

      with output

      2015-05-08T13:15:44.945-04:00[America/New_York]
      2015-05-08T13:15:46.051-04:00[America/New_York]
      -1
      false

      Adding nanos will also cause the return value to be correct, but not always.



      ADDITIONAL REGRESSION INFORMATION:
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      You can run this code:

      import java.time.ZoneId;
      import java.time.ZonedDateTime;

      public class Main {

          private static final ZoneId ET = ZoneId.of("America/New_York");

          public static void main(String[] args) {
              ZonedDateTime ts1 = ZonedDateTime.now(ET);
              ZonedDateTime ts2 = ZonedDateTime.now(ET);
              System.out.println(ts1);
              System.out.println(ts2);
              System.out.println(ts1.compareTo(ts2));
              System.out.println(ts1.equals(ts2));
          }
      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The third System.out.println should print -1.
      ACTUAL -
      The third System.out.println prints a number that is not -1, 1, or 0.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.time.ZoneId;
      import java.time.ZonedDateTime;

      public class Main {

          private static final ZoneId ET = ZoneId.of("America/New_York");

          public static void main(String[] args) {
              ZonedDateTime ts1 = ZonedDateTime.now(ET);
              ZonedDateTime ts2 = ZonedDateTime.now(ET).p;
              System.out.println(ts1);
              System.out.println(ts2);
              System.out.println(ts1.compareTo(ts2));
              System.out.println(ts1.equals(ts2));
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I convert the ZonedDateTimes to LocalDateTimes and compare them:

      import java.time.LocalDateTime;
      import java.time.ZoneId;
      import java.time.ZonedDateTime;

      public class Main {

          private static final ZoneId ET = ZoneId.of("America/New_York");

          public static void main(String[] args) {
              ZonedDateTime ts1 = ZonedDateTime.now(ET);
              ZonedDateTime ts2 = ZonedDateTime.now(ET);

              LocalDateTime ts3 = ts1.toLocalDateTime();
              LocalDateTime ts4 = ts2.toLocalDateTime();

              System.out.println(ts1);
              System.out.println(ts2);
              System.out.println(ts1.compareTo(ts2));
              System.out.println(ts1.equals(ts2));

              System.out.println(ts3);
              System.out.println(ts4);
              System.out.println(ts3.compareTo(ts4));

          }
      }

            rriggs Roger Riggs
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: