JDK-6358451 : (cal) GregorianCalendar fails to set HOUR after clone
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 5.0u5
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_10
  • CPU: sparc
  • Submitted: 2005-12-02
  • Updated: 2010-07-29
  • Resolved: 2005-12-06
Related Reports
Duplicate :  
Relates :  
Description
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

Comments
WORK AROUND Please use HOUR_OF_DAY to designate the time of the day.
06-12-2005

EVALUATION This is a duplicate of 6178071.
06-12-2005