Java Calendar Class

In the last lesson you learned about the Java Date class. You saw that most of its useful methods are broken or marked as old. So how did people read and change date parts before java.time arrived? They used the Calendar class.

πŸ€” The problem Calendar tried to solve

Date’s own field methods were buggy and got deprecated (marked as old and unsafe). So Java built java.util.Calendar to do that work safely.

  • Date holds a single moment. Deep down it is one number.
  • Calendar breaks that moment into parts: year, month, day, hour, more.
  • Calendar does math on those parts: add days, subtract months, and so on.

Think of Date as a photo of one instant. Calendar reads the wall calendar and counts forward or backward for you.

🧩 Getting a Calendar instance

You do not create a Calendar with new. The class is abstract, so you ask for one with a factory method called getInstance. A factory method is just a method that hands you a ready-made object.

The code below asks Java for a calendar set to right now.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());
}
}

Output

Sat Jun 13 10:45:12 IST 2026
  • getInstance gives you a calendar pointed at the current date and time.
  • getTime turns it back into a plain Date so it prints nicely (more on getTime later).

πŸ“… Reading fields with get

Read one piece of a date with get, passing a constant that says which piece you want. Those constants live inside the Calendar class.

The code below reads several parts of today’s date.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
System.out.println("Year: " + year);
System.out.println("Month: " + month);
System.out.println("Day: " + day);
System.out.println("Hour: " + hour);
System.out.println("Minute: " + min);
}
}

Output

Year: 2026
Month: 5
Day: 13
Hour: 10
Minute: 45

June 13 prints its month as 5, not 6. That is not a bug.

  • In Calendar, months start at zero: January is 0, December is 11.
  • So June, the sixth month, is 5.
  • This rule causes more date bugs than almost anything else in Java.

To stay safe, use Java’s named month constants. The code below uses one.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
if (cal.get(Calendar.MONTH) == Calendar.JUNE) {
System.out.println("It is June.");
}
}
}

Output

It is June.

Comparing against Calendar.JUNE instead of 5 makes your intent clear. The constant remembers that June is 5 so you do not have to.

✏️ Setting fields with set

The set method changes a calendar to point at any date you choose. It comes in two common shapes.

The code below sets one field at a time.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2030);
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 25);
System.out.println(cal.getTime());
}
}

Output

Wed Dec 25 10:45:12 IST 2030

Each set call changes one part and leaves the rest alone. The time of day stayed the same; only year, month, and day changed.

A shorter form sets the whole date in one line. The order is year, month, day.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
// year, month (0-based!), day
cal.set(2030, Calendar.DECEMBER, 25);
System.out.println(cal.getTime());
}
}

Output

Wed Dec 25 10:45:12 IST 2030

Even here the month is zero-based, so always use the constant like Calendar.DECEMBER. A raw 12 would roll over into January of the next year.

βž• Date arithmetic with add

The add method moves a date forward or backward. You say which field to change and by how much.

The code below adds five days to today.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println("Today: " + cal.getTime());
cal.add(Calendar.DAY_OF_MONTH, 5);
System.out.println("In 5 days: " + cal.getTime());
}
}

Output

Today: Sat Jun 13 10:45:12 IST 2026
In 5 days: Thu Jun 18 10:45:12 IST 2026

add handles the hard parts for you. The code below adds twenty days near the end of a month, and Calendar rolls into the next month correctly.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(2026, Calendar.JANUARY, 25);
cal.add(Calendar.DAY_OF_MONTH, 20);
System.out.println(cal.getTime());
}
}

Output

Sun Feb 14 10:45:12 IST 2026

January 25 plus 20 days lands in February. Calendar worked out that January has 31 days, so you never thought about month lengths or leap years.

Pass a negative number to go backward. The code below subtracts two months.

import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(2026, Calendar.JUNE, 13);
cal.add(Calendar.MONTH, -2);
System.out.println(cal.getTime());
}
}

Output

Mon Apr 13 10:45:12 IST 2026

A negative amount walks the date the other way. June minus two months is April.

πŸ”„ Converting between Calendar and Date

Older code passes Date objects around, so you often move between the two. Two methods bridge them.

getTime turns a Calendar into a Date. The name is confusing, but it means β€œgive me this as a Date”. The code below shows it.

import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
System.out.println(now);
}
}

Output

Sat Jun 13 10:45:12 IST 2026

Going the other way, setTime loads a Date into a Calendar so you can read its parts. The code below pulls the year out of a Date.

import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date someDate = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(someDate);
System.out.println("Year: " + cal.get(Calendar.YEAR));
}
}

Output

Year: 2026

The pattern: setTime to load a Date in, read or change fields, then getTime to get a Date back out.

⚠️ Common Mistakes

A few traps catch almost everyone who uses Calendar.

The month is zero-based. Writing the plain number gives you the wrong month.

// ❌ Wrong: this sets the month to June, not May
cal.set(Calendar.MONTH, 5);
// βœ… Right: use the named constant
cal.set(Calendar.MONTH, Calendar.MAY);

The constant says what you mean, so you never count from zero in your head.

Calendar is mutable, so changing it changes the original. If you hand the same Calendar to a method and it calls add, your object changes too.

// ❌ Risky: add() changes cal in place, affecting everyone holding it
cal.add(Calendar.DAY_OF_MONTH, 7);
// βœ… Safer: clone first, then change the copy
Calendar copy = (Calendar) cal.clone();
copy.add(Calendar.DAY_OF_MONTH, 7);

Cloning gives you a separate calendar, so the original stays as it was.

The code is verbose. Even a simple task takes many lines and constants. Compare two ways of building one date.

// ❌ Clunky: several lines and the zero-based month trap
Calendar cal = Calendar.getInstance();
cal.set(2026, Calendar.JUNE, 13);
Date d = cal.getTime();
// βœ… Clean: java.time reads like plain English, month is 6 = June
LocalDate date = LocalDate.of(2026, 6, 13);

The modern version is one line, the month matches real life, and it cannot be changed by accident.

βœ… Best Practices

Calendar works, but it is from an older era of Java. For new code:

  • Prefer java.time. Classes like LocalDate, LocalDateTime, and ZonedDateTime are clear, safe, and hard to misuse.
  • When you must use Calendar, use named month constants like Calendar.MARCH, not raw numbers. This removes the zero-based trap.
  • Copy a Calendar you receive with clone before changing it, so you do not surprise code that shares it.
  • Convert a Date or Calendar from old code into java.time early, work there, and convert back only at the edge.

Keep Calendar for old projects, not as your first choice. It taught Java a lesson, and java.time is the result.

πŸ“ What You’ve Learned

  • Calendar was the older fix for the broken methods on Date.
  • You get one with Calendar.getInstance, not with new.
  • You read parts with get and constants like Calendar.YEAR and Calendar.DAY_OF_MONTH.
  • The month field is zero-based, so January is 0 and June is 5. Use named constants to stay safe.
  • You change parts with set and move dates with add, which handles month lengths and leap years for you.
  • getTime and setTime convert between Calendar and Date.
  • Calendar is mutable and verbose, so java.time is preferred for new code.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    How do you get a Calendar instance?

    Why: Calendar is abstract, so you use the factory method Calendar.getInstance() instead of new.

  2. 2

    If cal.get(Calendar.MONTH) returns 5, which month is it?

    Why: Calendar months are zero-based, so 0 is January and 5 is June.

  3. 3

    What does cal.add(Calendar.DAY_OF_MONTH, 5) do?

    Why: add changes the calendar in place, rolling into the next month if needed.

  4. 4

    Which method turns a Calendar into a Date?

    Why: getTime() returns the Calendar's moment as a java.util.Date, and setTime() loads a Date back in.

πŸš€ What’s Next?

You now know Calendar, the old way to read and change date parts. But you also saw that it is clunky and easy to get wrong. The modern answer is the java.time package, and the best place to start there is the class for a date with no time attached. Let’s learn it.

Java LocalDate

Share & Connect