-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
5.0u5
-
sparc
-
solaris_10
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
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
- duplicates
-
JDK-6178071 (cal) REGRESSION: GregorianCalendar.set(Calendar.HOUR, ...) has no effect
- Resolved
- relates to
-
JDK-4026300 Gregorian Calendar clone problem
- Closed