This section provides a tutorial example on how to use the java.util.Calendar.add() method to manipulate any elements in a calendar object.
Objects of Date class are easy to be manipulated, since each of them has only
one numerical field in unit of millisecond. For example, to calculate the number
of full days between two Date objects, you can use the following expression:
However, objects of Calendar are not so easy to be manipulated, since each of them
has many related numerical fields in different calendar units. For example, incrementing
the day-in-month field by 1, may affect the month field, if the Calendar object is
at the end of a month; then the change in the month field may affect the year field,
if the Calendar object is at the end of a year.
To help us manipulate Calendar objects safely, JDK offers the following method:
add(int field, int delta)
with two rules:
The new value of the specified field is the old value plus the delta, and
modulo any overflow. If overflow occurs, the next higher field will incremented
or decremented.
If the new value of the specified field is causing changes on the value range
of the next lower field, that field needs to be adjusted.
The following program demontrates how the add() method works:
import java.util.*;
class DateOperationTest {
public static void main(String[] a) {
GregorianCalendar dt = new GregorianCalendar();
dt.set(2002,9,31); //31-Oct-2002
System.out.println("Current time: "+dt.getTime().toString());
dt.add(Calendar.DATE,1);
System.out.println("Add 1 to date: "+dt.getTime().toString());
dt.set(2002,9,31); //31-Oct-2002
System.out.println("Current time: "+dt.getTime().toString());
dt.roll(Calendar.DATE,1);
System.out.println("Roll 1 to date: "+dt.getTime().toString());
dt.set(2002,9,31); //31-Oct-2002
System.out.println("Current time: "+dt.getTime().toString());
dt.add(Calendar.MONTH,1);
System.out.println("Add 1 to month: "+dt.getTime().toString());
GregorianCalendar dt1 = new GregorianCalendar();
GregorianCalendar dt2 = new GregorianCalendar();
dt1.set(2002,9,31,0,0,0);
dt2.set(2002,10,1,0,0,0);
System.out.println(" From: "+dt1.getTime().toString());
System.out.println(" To: "+dt2.getTime().toString());
long days = fullDayDiff(dt1,dt2);
System.out.println("Full days: "+days);
dt1.set(2002,9,31,0,0,0);
dt2.set(2002,10,30,0,0,0);
System.out.println(" From: "+dt1.getTime().toString());
System.out.println(" To: "+dt2.getTime().toString());
long months = fullMonthDiff(dt1,dt2);
System.out.println("Full months: "+months);
dt1.set(2002,9,30,0,0,0);
dt2.set(2003,10,29,0,0,0);
System.out.println(" From: "+dt1.getTime().toString());
System.out.println(" To: "+dt2.getTime().toString());
months = fullMonthDiff(dt1,dt2);
System.out.println("Full months: "+months);
}
public static long fullDayDiff(Calendar dt1, Calendar dt2) {
long tm1 = dt1.getTime().getTime();
long tm2 = dt2.getTime().getTime();
return (tm2-tm1)/(1000*60*60*24);
}
public static long fullMonthDiff(Calendar dt1, Calendar dt2) {
// Both dates are truncated to the beginning of the day
// dt1 and dt2 are damaged
// 30-Oct-2002 to 30-Nov-2002: 1 month
// 31-Oct-2002 to 30-Nov-2002: 1 month
// 30-Oct-2002 to 29-Nov-2002: < 1 month
Calendar a, b;
if (dt1.before(dt2)) {
a = dt1;
b = dt2;
} else {
a = dt2;
b = dt1;
}
// work on the years
int y1 = a.get(Calendar.YEAR);
int y2 = b.get(Calendar.YEAR);
int m1 = a.get(Calendar.MONTH);
int m2 = b.get(Calendar.MONTH);
int l = y2 - y1;
if (m2<m1) l--;
int diff = 0;
if (l>0) {
diff += l*12;
a.add(Calendar.YEAR,l);
}
// work on the months
y1 = a.get(Calendar.YEAR);
y2 = b.get(Calendar.YEAR);
m1 = a.get(Calendar.MONTH);
m2 = b.get(Calendar.MONTH);
if (m2<m1) {
l = m2 + 12 - m1;
} else {
l = m2 - m1;
}
l = m2 - m1;
if (l>0) {
diff += l;
a.add(Calendar.MONTH,1);
}
// date adjustment
int d1 = a.get(Calendar.DATE);
int d2 = b.get(Calendar.DATE);
if (d2<d1) diff--;
return diff;
}
}
Output:
Current time: Thu Oct 31 19:02:19 EST 2002
Add 1 to date: Fri Nov 01 19:02:19 EST 2002
Current time: Thu Oct 31 19:02:19 EST 2002
Roll 1 to date: Tue Oct 01 19:02:19 EDT 2002
Current time: Thu Oct 31 19:02:19 EST 2002
Add 1 to month: Sat Nov 30 19:02:19 EST 2002
From: Thu Oct 31 00:00:00 EST 2002
To: Fri Nov 01 00:00:00 EST 2002
Full days: 1
From: Thu Oct 31 00:00:00 EST 2002
To: Sat Nov 30 00:00:00 EST 2002
Full months: 1
From: Wed Oct 30 00:00:00 EST 2002
To: Sat Nov 29 00:00:00 EST 2003
Full months: 12
Note that I have only done few tests on the fullMonthDiff() method. So don't take it
to your program directly. Do more tests yourself.
Exercise: Write a program to calculate the annually compound interest of an
investment with the following method signature: