JDK (Java Development Kit) Tutorials
Dr. Herong Yang, Version 5.00

java.util.Calendar.add() - Calendar Manipulation Method

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:

   (date1.getTime() - date2.getTime()) / (1000*60*60*24)

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:

   public static double getInterest(double capital, 
      double interest_rate, Calendar start_date, Calendar end_date)

Sections in This Chapter

java.util.Date - JDK Class to Measure Date and Time

java.util.Calendar - The Abstract Calendar Class

java.util.Calendar.add() - Calendar Manipulation Method

Dr. Herong Yang, updated in 2008
java.util.Calendar.add() - Calendar Manipulation Method