Java has several ways of representing dates. Let’s delve into them now.

java.util.Date and java.sql.Date

Note that we’ve specified the packages for these two classes, since they have the same name. They differ mainly in how to create instances.

java.util.Date is the simpler of the two. These statements:

    import java.util.Date
    ...
    Date now = new Date();

set now to the current date and time, to the millisecond.

java.sql.Date exists to hold dates for use with DATE fields in SQL databases. These don’t have a time-of-day component, so it’s assumed that the milliseconds, seconds, minutes, and hours are all zero; regrettably, unless the value has been read from a database or from the valueOf() function (below), this isn’t automatic. java.sql.Date does not have a default constructor, but the static valueOf() function lets you initialize an instance with the date of your choosing:

    import java.sql.Date;
    ...
    Date independenceDay = Date.valueOf("1776-07-04");

These two classes do have one common constructor: new Date(long date), where date is a value in milliseconds since January 1, 1970.

    Date myDate = new Date(<time in milliseconds>);

In fact, the value of either Date class is the number of milliseconds elapsed since midnight GMT, January 1, 1970 (known as the epoch).

Thus you can go from an instance of one class to an instance of the other:

    java.util.Date now = new Date();
    java.sql.Date sqlNow = new java.sql.Date(now.getTime());

Note that in this scenario, sqlNow will have a nonzero milliseconds, seconds, minutes, and hours–which is not allowed! We’ll give you a neat way of fixing this later.

Methods for java.util.Date and java.sql.Date

Aside from the constructors and method mentioned above, the methods for the two Date classes are identical:

MethodFunction
boolean after(Date when)
boolean before(Date when)
Returns true if this date is later than/earlier than when.
Equivalent to this.compareTo(when) > 0 and this.compareTo(when) < 0, respectively.
int compareTo(Date anotherDate)Returns a value less than zero if the current date precedes anotherDate, greater than zero if current date follows anotherDate, and zero if they are equal.
long getTime()Returns the number of milliseconds since midnight GMT, Jan. 1, 1970.
setTime(long time)Sets the value to time, which is the number of milliseconds since midnight GMT, Jan. 1, 1970.

Calendar

The two Date classes may suit you just fine most of the time. But if you need to do date or time arithmetic, or find information such as the day of the week a date represents, you need the Calendar class which, like Date, contains both a date and a time represented as milliseconds since midnight GMT, January 1, 1970.

Calendar is, in fact, an abstract class. It provides a method, getInstance(), to return an concrete instance of a subclass initialized to the current date and time. In almost all instances, the class returned is GregorianCalendar. The getInstance() method accepts as arguments a Locale, a TimeZone, neither, or both, which govern the behavior of the underlying concrete class. For example, this statements executed on a computer in the United States…

   Calendar usCal = Calendar.getInstance();
   Calendar frenchCal = Calendar.getInstance(Locale.FRANCE);

makes usCal a default Calendar for which the first day of the week is Sunday, and frenchCal a Calendar for which the first day of the week is Monday.

Calendar, and by extension GregorianCalendar, have an amazing array of methods and constants useful for date inquiry and manipulation. Please check the documentation for Calendar and GregorianCalendar for complete lists, and detailed descriptions of how these classes function. (Just follow the links in this paragraph.) Here’s a sampling:

ConstantDescription
APRILA value representing April
DATE
DAY_OF_MONTH
Two synonymous field type identifiers for the day of the month
MONDAYA value representing Monday
DAY_OF_YEARA field type identifier for the day of the year
HOURA field type identifier for the hour of the morning or afternoon
HOUR_OF_DAYA field type identifier for the hour of the day (e.g., for 2:15 PM, HOUR_OF_DAY is 14)
A sampling of Calendar class constants
MethodDescription
void add(int field, int amount)Adds amount to the field indicated by field. amount may be negative. Example:
cal.add(Calendar.DAY_OF_WEEK, -1);
changes the calendar’s date to the previous day.
boolean before(Object when)
boolean after(Object when)
boolean compareTo(Object when)
These behave the same as they do for Date, but notice that any compatible type of object may be provided for when.
int get(int field)Returns the current value of the indicated field. Example:
int theYear = cal.get(Calendar.YEAR);
sets theYear to the value of the calendar year.
void roll(int field, boolean up)
void roll(int field, int amount)
Rolls the indicated field up/down one unit of time (first version), or the desired amount of units of time, without changing other fields. Examples:
cal.roll(Calendar.MONTH, true);
sets the month to the next value.
cal.roll(Calendar.MONTH, -3);
sets the month to three months earlier.
int getFirstDayOfWeek()
void setFirstDayOfWeek(int value)
Returns or sets the day of the week (Calendar.SUNDAY, Calendar.MONDAY, … Calendar.SATURDAY) the Calendar uses as the first day of a week.
int get(int field)Returns the current value of the indicated field. Example:
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
returns the cal’s current day-of-week value.
void set(int field, int value)Sets the indicated field to the specified value. Example:
cal.set(Calendar.MINUTE, 59);
sets the current minute value of cal to 59.
java.util.Date getTime()Returns the java.util.Date value of the Calendar (i.e., date and time).
A sampling of Calendar methods

It may have occurred to you that if your Calendar is set to February 29 and you set its Calendar.DAY_OF_MONTH to 30, your date is now February 30. Or if you roll the minute of the time 06:28:32 up by a Calendar.HOUR value of 20, the time of day is now 26:28:32.

Whenever you change a Calendar field using set() or roll(), Calendar not only makes the value change; it records it. The next time get(), getTime(), getTimeInMillis(), add(), or roll() is called, all the pending value changes are used to recompute the Calendar’s value in milliseconds. (On the other hand, a call to add() recomputes the value immediately.)

The results can be complex, and we again refer you to the documentation for a full explanation. For example (taken from the documentation), if a GregorianCalendar is set to August 31, 1999, this call:

    cal.set(Calendar.MONTH, Calendar.SEPTEMBER);

changes the value to September 31, 1999. This will resolve to October 1, 1999 if getTime() is called. But if this call is made before getTime():

    cal.set(Calendar.DAY_OF_MONTH, 30);

the date will be September 30, 1999, since a call to set() doesn’t force the recomputation first.

Exercise

Write a program to display the dates of Labor Day in the United States for the years 2011 through 2025. You can use toString() to format the resulting dates. Your output should look something like this:

Labor Day 2011 is Mon Sep 05 13:16:57 EEST 2011
Labor Day 2012 is Mon Sep 03 13:16:57 EEST 2012
Labor Day 2013 is Mon Sep 02 13:16:57 EEST 2013
Labor Day 2014 is Mon Sep 01 13:16:57 EEST 2014
Labor Day 2015 is Mon Sep 07 13:16:57 EEST 2015
Labor Day 2016 is Mon Sep 05 13:16:57 EEST 2016
Labor Day 2017 is Mon Sep 04 13:16:57 EEST 2017
Labor Day 2018 is Mon Sep 03 13:16:57 EEST 2018
Labor Day 2019 is Mon Sep 02 13:16:57 EEST 2019
Labor Day 2020 is Mon Sep 07 13:16:57 EEST 2020
Labor Day 2021 is Mon Sep 06 13:16:57 EEST 2021
Labor Day 2022 is Mon Sep 05 13:16:57 EEST 2022
Labor Day 2023 is Mon Sep 04 13:16:57 EEST 2023
Labor Day 2024 is Mon Sep 02 13:16:57 EEST 2024
Labor Day 2025 is Mon Sep 01 13:16:57 EEST 2025

Once you’re done–or if you’re stuck–download a possible solution here. Our version uses a couple of tricks you might not have thought of. Good luck!

DateUtils

It’s not always easy to deal with dates and calendars. Fortunately, there are third parties ready to help. One of the most prominent is the Apache Software Foundation’s Apache Commons project. Their mission: to produce reusable Java software components. We’ve included some of their software in the Libs project we created as part of setup.

The component we’re interested in here is the DateUtils class. Here’s how to add it to your project.

  1. In Eclipse, open the Libs project we created in Lesson 3.
  2. Right-click on your project in the Package Explorer and select Build Path/Configure Build Path. Click on Classpath in the window in the center, then click on Add JARs…. Expand the Libs node and you’ll see a dialog similar to this:

    Configure Build Path dialog
  3. Click on the JAR to select it and click OK. You’ve now added the JAR to the build classpath and have access to all its code.

What Is a JAR?

You’ve just added a JAR (Java Archive) to your build classpath, and will probably put it in an execution classpath as well. A JAR is nothing more than a ZIP file of compiled Java classes and/or other resources, arranged in a directory structure. The compiler and the JVM treat a JAR just as though the directories and files it contains actually appeared in a file system, but in a more portable format.

It may well happen that you discover you have need of a class from a JAR you don’t have on hand. When this happens, the solution is to download an appropriate JAR from the Internet. There are web sites like jar.download.com, devoted to helping you find JARs by searching on the name of the class you need.

Back to DateUtils

As we said, the Apache DateUtils class contains methods and constants for working with dates. Please follow this link for more information, but here are some of its more useful methods and fields.

FieldDescription
static long MILLIS_PER_DAY
static long MILLIS_PER_HOUR
static long MILLIS_PER_MINUTE
static long MILLIS_PER_SECOND
Number of milliseconds in a standard day/hour/minute/second
Sampling of constants in DateUtils
MethodDescription
public static boolean
isSameDate(Date date1, Date date2
Returns a boolean indicating whether the two dates are the same day, irrespective of time of day.
public static boolean
isSameDate(Calendar cal1, Calendar cal2
Returns a boolean indicating whether the two calendars are the same day, irrespective of time of day.
public static Date parseDate
(String str, String… parsePatterns)
throws ParseException
Parses str against one or more parsePattern patterns, returning the first successful parsed value. Each parsePattern is in the form of a SimpleDateFormat expression.
parseDate has a number of overloads; see the documentation for details.
public static Date
 addYears(Date date, int amount)
public static Date
 addMonths(Date date, int amount)
public static Date
 addWeeks(Date date, int amount)
public static Date
 addDays(Date date, int amount)
public static Date
 addHours(Date date, int amount)
public static Date
 addMinutes(Date date, int amount)
public static Date
 addSeconds(Date date, int amount)
public static Date
 addMilliseconds(Date date, int amount)
Adds the amount (which may be negative) to the pertinent time unit in date and returns the result, leaving date unchanged.
public static Date
 setYears(Date date, int amount)
public static Date
 setMonths(Date date, int amount)
public static Date
 setWeeks(Date date, int amount)
public static Date
 setDays(Date date, int amount)
public static Date
 setHours(Date date, int amount)
public static Date
 setMinutes(Date date, int amount)
public static Date
 setSeconds(Date date, int amount)
public static Date
 setMilliseconds(Date date, int amount)
Sets the pertinent time unit in date to amount and returns the result, leaving date unchanged.
public static Calendar
 toCalendar(Date date)
Converts date to a Calendar.
public static Date
 round(Date date, int field)
public static Calendar
 round(Calendar date, int field)
Rounds a date/time, leaving the field specified as the most significant field.
For example, if date is 28 Mar 2002 13:45:01.231 and field is Calendar.HOUR, the result is 28 Mar 2002 14:00:00.000.
public static Date
 truncate(Date date, int field)
public static Calendar
 truncate(Calendar date, int field)
Truncates a date/time to the field specified.
For example, if date is 28 Mar 2002 13:45:01.231 and field is Calendar.HOUR, the result is 28 Mar 2002 13:00:00.000.
public static Date
 ceiling(Date date, int field)
public static Calendar
 ceiling(Calendar date, int field)
Gets a date ceiling, leaving the field specified as the most significant field.
For example, if date is 28 Mar 2002 13:45:01.231 and field is Calendar.HOUR, the result is 28 Mar 2002 14:00:00.000.
Sampling of DateUtils methods

What You Need to Know

  • Java as two Date classes for simple handling of date/time values.
  • Java has a Calendar class for date computations.
  • The Apache Software Foundation is dedicated to providing open-source Java components.
  • DateUtils is a class of useful Date and Calendar methods.

Next up: Internal and External Representations, and Formatting