Java's java.util.Calendar and GregorianCalendar
Jakob Jenkov |
Java's java.util.Calendar
class is used to do date and time
arithmetic. Whenever you have something slightly more advanced than
just representing a date and time, this is the class to use.
The java.util.Calendar
class is abstract, meaning you cannot instantiate it.
The reason is that there are more than one calendar in the world. For instance, the Arab
calendar uses a different year as year 0 than the Gregorian calendar used by most western
countries.
Instantiating a GregorianCalendar
Java only comes with a Gregorian calendar implementation, the java.util.GregorianCalendar
class. Here is how you instantiate a GregorianCalendar
:
Calendar calendar = new GregorianCalendar();
A new GregorianCalendar
has the date and time set to "now", meaning the
date and time it was created.
Accessing Year, Month, Day etc.
The Calendar
class has a couple of methods you can use to access the year,
month, day, hour, minutes, seconds, milliseconds and time zone of a given date. Here
are a few examples showing how that is done:
Calendar calendar = new GregorianCalendar(); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); // Jan = 0, not 1 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR); int weekOfMonth= calendar.get(Calendar.WEEK_OF_MONTH); int hour = calendar.get(Calendar.HOUR); // 12 hour clock int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 hour clock int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); int millisecond= calendar.get(Calendar.MILLISECOND);
There are a few more fields that you can access, like DAY_OF_WEEK_IN_MONTH
and AM_PM
which are not used so often.
Check out the official JavaDoc to learn more about those fields.
The Calendar
class has a corresponding set()
method so you
can set these fields too. Here is how that looks:
Calendar calendar = new GregorianCalendar(); calendar.set(Calendar.YEAR, 2009); calendar.set(Calendar.MONTH, 11); // 11 = december calendar.set(Calendar.DAY_OF_MONTH, 24); // christmas eve etc.
Adding and Subtracting to Year, Month, Day etc.
You can also add to these fields and have the Calendar
instance
update itself correctly. Look at this example:
Calendar calendar = new GregorianCalendar(); //set date to last day of 2009 calendar.set(Calendar.YEAR, 2009); calendar.set(Calendar.MONTH, 11); // 11 = december calendar.set(Calendar.DAY_OF_MONTH, 31); // new years eve //add one day calendar.add(Calendar.DAY_OF_MONTH, 1); //date is now jan. 1st 2010 int year = calendar.get(Calendar.YEAR); // now 2010 int month = calendar.get(Calendar.MONTH); // now 0 (Jan = 0) int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); // now 1
The add()
method is really handy when doing date arithmetics like
adding or subtracting years, months, days, hours etc. from a given date.
To subtract from the fields call the add()
method with negative
values, like this:
calendar.add(Calendar.DAY_OF_MONTH, -1);
Traps and Pitfalls
There are a few minor traps in the Calendar
class that you
should be aware of to avoid unnecessary headaches. I'll cover those in
the following sections.
The Month Trap
The MONTH
field of the Calendar
class does not
go from 1 to 12 like they do when we write dates otherwise. Instead the
months run from 0 to 11, where 0 is January and 11 is December. This can
cause a bit of errors and subsequent debugging if you are not aware of this.
The Day of Week Trap
The day of week runs from 1 to 7 as you might expect, but sunday, not monday is the first day of the week. That means that 1 = sunday, 2 = monday, ..., 7 = saturday. This has also caused me minor annoyances from time to time.
More Detail in the JavaDoc
If you need to do heavy or complex date and time calculations it is a good idea
to read the class documentation for java.util.Calendar
in the official
JavaDoc's. The class documentation contains more detail about the specific behaviour
of the class. For instance if you set the date to Jan. 34th 2009, what will the
real date be?
Tweet | |
Jakob Jenkov |