Calendar clone problem
Date: Jul 31, 2010 @ 20:23

There are two ways to get Calendar instance, one to use GregorianCalendar.getInstance() and another DateFormat.getCalandar(). There is one basic problem if you use DateFormat.getCalendar() approcah. Let sess this by an example.


Cloning of Caneldar object from DateFormat.getInstance():-
 
import java.text.DateFormat;
import java.util.Calendar;
public class Test {
public static void main(String[] args)
{
DateFormat dateFormat = DateFormat.getDateInstance();
Calendar baseCalendar = dateFormat.getCalendar();
Calendar workCalendar = null;
for(int i = 1; i < 6; i++)
{
workCalendar = (Calendar) baseCalendar.clone();
workCalendar.add(Calendar.MONTH, 1);
System.out.println("base:" +dateFormat.format(baseCalendar.getTime()));
System.out.println("work:" +dateFormat.format(workCalendar.getTime()));
workCalendar = null;
}
}
}

Here we are getting Canendar object using DateFormat.getCalendar() method and cloning it and modifying the object that we received from colning. We expect this to be a deep copy but it is not. Even if we modify clonned object(workCalendar) our original object will also change.

Output:-
 
base:Jul 31, 1930
work:Aug 31, 1930
base:Aug 31, 1930
work:Sep 30, 1930
base:Sep 30, 1930
work:Oct 30, 1930
base:Oct 30, 1930
work:Nov 30, 1930
base:Nov 30, 1930
work:Dec 30, 1930

If you see after each ineration or base object is also changing even if we changed the clonned object.

Now let us see this by a calendar instance using GregorianCalendar.

Here is the program:-
 
public class Test {
public static void main(String[] args)
{
DateFormat dateFormat = DateFormat.getDateInstance();
Calendar baseCalendar = GregorianCalendar.getInstance();
Calendar workCalendar = null;
for(int i = 1; i < 6; i++)
{
workCalendar = (Calendar) baseCalendar.clone();
workCalendar.add(Calendar.MONTH, 1);
System.out.println("base:" +dateFormat.format(baseCalendar.getTime()));
System.out.println("work:" +dateFormat.format(workCalendar.getTime()));
workCalendar = null;
}
}
}
 Output:-
base:Jul 31, 2010
work:Aug 31, 2010
base:Jul 31, 2010
work:Aug 31, 2010
base:Jul 31, 2010
work:Aug 31, 2010
base:Jul 31, 2010
work:Aug 31, 2010
base:Jul 31, 2010
work:Aug 31, 2010

If you see the output then you realize that even if we modify the clonned object base does not change. Calendar oject created using DateFormat can create possible bug in the program. It is always bette to use GregorianCalendar approcah.