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

(cal) GregorianCalendar fails to set HOUR after clone

XMLWordPrintable

      If you clone() a GregorianCalendar and set(Calendar.HOUR,..), then methods getTime().toString() and equals() do not get the new hour, if running 1.5.0_05
      Using 1.4.2_09 it works
      The behaviour is different if we add set(Calendar.DAY_OF_MONTH,..), because both java version can see the new day, but the hour is still wrong in 1.5.0_05

      I have included in an old testcase (see Test.java of 4026300 which still fails using 1.5.0_05) the method getDateDiff() similar to a Sun UWC method; in this method equals() is executed in a loop so the error setting the hour can lead to an unexpected behaviour in the original application

      import java.io.*;
      import java.util.*;
      class DiffTest {
      public static void main(String[] args) {

      DiffTest difftest = new DiffTest();
      difftest.test();
      }

      public void test () {

        GregorianCalendar d1, d2, d3;
        d1 = new GregorianCalendar(1997,1,16);
        d2 = (GregorianCalendar) d1.clone();
        // If you set the day for d2 and d3, then equals() detect the difference
        d2.set(Calendar.HOUR, 10);
        // d2.set(Calendar.DAY_OF_MONTH, 17);
        // System.out.println(d2.getTime().toString());
        d3 = (GregorianCalendar) d1.clone();
        d3.set(Calendar.HOUR, 11);
        // d3.set(Calendar.DAY_OF_MONTH, 18);
        System.out.println(d1.getTime().toString() +
                           "\n" + d2.getTime().toString() +
                           "\n" + d3.getTime().toString());
        System.out.println("Legenda for count values: 0 (first smaller) 1 (same value) n (different values)");
        System.out.println("count from " + d1.getTime() + " to " + d2.getTime() + " = " + getDateDiff(d1,d2));
        System.out.println("count from " + d1.getTime() + " to " + d3.getTime() + " = " + getDateDiff(d1,d3));
        System.out.println("count from " + d2.getTime() + " to " + d3.getTime() + " = " + getDateDiff(d2,d3));
      }

      private int getDateDiff(GregorianCalendar stDt, GregorianCalendar endDt)// throws PropertiesException
        {
           GregorianCalendar clone_dtst = (GregorianCalendar)stDt.clone();
           GregorianCalendar clone_dtend = (GregorianCalendar)endDt.clone();
           //Reset the hour minute,seconds and miliseconds components to 0
           //clone_dtst.set(Calendar.HOUR, 0);
           clone_dtst.set(Calendar.MINUTE, 0);
           clone_dtst.set(Calendar.SECOND, 0);
           clone_dtst.set(Calendar.MILLISECOND, 0);
           // reset to the original day
           // clone_dtst.set(Calendar.DAY_OF_MONTH,stDt.get(Calendar.DAY_OF_MONTH));
           //
           // clone_dtend.set(0, 0, 0);
           //clone_dtend.set(Calendar.HOUR, 0);
           clone_dtend.set(Calendar.MINUTE, 0);
           clone_dtend.set(Calendar.SECOND, 0);
           clone_dtend.set(Calendar.MILLISECOND, 0);
           // reset to the original day
           // clone_dtend.set(Calendar.DAY_OF_MONTH,endDt.get(Calendar.DAY_OF_MONTH));

           // From http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html#after(java.util.Date)
           // true if and only if the instant represented by this Date object is strictly later than
           // the instant represented by when; false otherwise.
           if(clone_dtst.after(clone_dtend))
             return 0;

           int count = 1;

           // http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html#equals(java.lang.Object)
           // Compares two dates for equality. The result is true if and only if the argument is not null
           // and is a Date object that represents the same point in time, to the millisecond, as this object.
           // Thus, two Date objects are equal if and only if the getTime method returns the same long value for both.
           //
           // http://java.sun.com/j2se/1.5.0/docs/api/java/util/GregorianCalendar.html#equals(java.lang.Object)
           // Compares this GregorianCalendar to the specified Object. The result is true if and only if the argument
           // is a GregorianCalendar object that represents the same time value (millisecond offset from the Epoch)
           // under the same Calendar parameters and Gregorian change date as this object.
           while( !clone_dtst.equals(clone_dtend) )
           {
             clone_dtst.add(Calendar.HOUR,1);
             // clone_dtst.add(Calendar.DAY_OF_YEAR,1);
             count++;
           }
           return count;
        }
      }

      % /usr/j2se/bin/javac DiffTest.java

      % /usr/j2se/bin/java -showversion DiffTest
      java version "1.4.2_09"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_09-b03)
      Java HotSpot(TM) Client VM (build 1.4.2_09-b03, mixed mode)

      Sun Feb 16 00:00:00 MET 1997
      Sun Feb 16 10:00:00 MET 1997
      Sun Feb 16 11:00:00 MET 1997
      Legenda for count values: 0 (first smaller) 1 (same value) n (different values)
      count from Sun Feb 16 00:00:00 MET 1997 to Sun Feb 16 10:00:00 MET 1997 = 11
      count from Sun Feb 16 00:00:00 MET 1997 to Sun Feb 16 11:00:00 MET 1997 = 12
      count from Sun Feb 16 10:00:00 MET 1997 to Sun Feb 16 11:00:00 MET 1997 = 2

      % java -showversion DiffTest
      java version "1.5.0_05"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

      Sun Feb 16 00:00:00 MET 1997
      Sun Feb 16 00:00:00 MET 1997
      Sun Feb 16 00:00:00 MET 1997
      Legenda for count values: 0 (first smaller) 1 (same value) n (different values)
      count from Sun Feb 16 00:00:00 MET 1997 to Sun Feb 16 00:00:00 MET 1997 = 1
      count from Sun Feb 16 00:00:00 MET 1997 to Sun Feb 16 00:00:00 MET 1997 = 1
      count from Sun Feb 16 00:00:00 MET 1997 to Sun Feb 16 00:00:00 MET 1997 = 1

      If you set DAY_OF_MONTH to something, then with equals() we can count the days, in hours, on both versions (count = 24+10+1, 48+11+1, 24+1+1), but in 1.5 still without detecting the HOUR we have previously set (count = 24+0+1, 48+0+1, 24+0+1)

      In test() removing comments of

      //d2.set(Calendar.DAY_OF_MONTH, 17);
      //d3.set(Calendar.DAY_OF_MONTH, 18);

      you get:

      % /usr/j2se/bin/javac DiffTest.java

      % /usr/j2se/bin/java -showversion DiffTest
      java version "1.4.2_09"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_09-b03)
      Java HotSpot(TM) Client VM (build 1.4.2_09-b03, mixed mode)

      Sun Feb 16 00:00:00 MET 1997
      Mon Feb 17 10:00:00 MET 1997
      Tue Feb 18 11:00:00 MET 1997
      Legenda for count values: 0 (first smaller) 1 (same value) n (different values)
      count from Sun Feb 16 00:00:00 MET 1997 to Mon Feb 17 10:00:00 MET 1997 = 35
      count from Sun Feb 16 00:00:00 MET 1997 to Tue Feb 18 11:00:00 MET 1997 = 60
      count from Mon Feb 17 10:00:00 MET 1997 to Tue Feb 18 11:00:00 MET 1997 = 26

      % java -showversion DiffTest
      java version "1.5.0_05"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

      Sun Feb 16 00:00:00 MET 1997
      Mon Feb 17 00:00:00 MET 1997
      Tue Feb 18 00:00:00 MET 1997
      Legenda for count values: 0 (first smaller) 1 (same value) n (different values)
      count from Sun Feb 16 00:00:00 MET 1997 to Mon Feb 17 00:00:00 MET 1997 = 25
      count from Sun Feb 16 00:00:00 MET 1997 to Tue Feb 18 00:00:00 MET 1997 = 49
      count from Mon Feb 17 00:00:00 MET 1997 to Tue Feb 18 00:00:00 MET 1997 = 25

            okutsu Masayoshi Okutsu
            cmassi Claudio Massi (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: