Problem with Calendar in Java 5.
Hi folks !!
We are moving to Java 5 (too late... I know...) and I found and interesting
issue about Calendar.
Consider the problem of having a date allways in 00h00 time.
One possible solution is what we have in our code:
import java.util.Calendar;
publicclass CalendarTest{
publicstaticvoid main(String[] args){
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2007);
cal.clear(Calendar.HOUR);
cal.clear(Calendar.HOUR_OF_DAY);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
}
}
Compiling and running it with Java 1.4 we'll see the following output (I live in brazil, GMT-3 timezone):
Thu Mar 01 00:00:00 GMT-03:00 2007
1172718000000
But if you compile and run it with Java 1.5 you'll see:
Thu Mar 01 12:00:00 GMT-03:00 2007
1172761200000
The hour wasn't cleared !!
The most interesting is that it happens after noon. If I run it before noon the both outputs are the same.
Now let's see what Java 1.5 JavaDoc says about the "clear(int)" method of Calendar:
"Sets the given calendar field value and the time value (millisecond offset from the Epoch)
of this Calendar undefined. (...) The HOUR_OF_DAY, HOUR and AM_PM fields are handled
independently and the the resolution rule for the time of day is applied. Clearing one of
the fields doesn't reset the hour of day value of this Calendar.
Use set(Calendar.HOUR_OF_DAY, 0) to reset the hour value."
The Java 1.4 JavaDoc just says:
"Clears the value in the given time field."
The solution is to follow the 1.5 Javadoc and use "set(int, 0)" ao inv閟 de "clear()":
publicclass CalendarTest{
publicstaticvoid main(String[] args){
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2007);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
}
}
You can use this solution too:
publicclass CalendarTest{
publicstaticvoid main(String[] args){
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2007);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
}
}
But in my opinion the last one doesn't seem to be the best solution due to definition
of "clear()" method that says the fields will be set undefined, after all undefined
is not the same as zero :)
Can you reproduce this bug in your enviroment ? Do you consider this a bug ?
Thanks for your attention.

