Working
with dates and times without the proper tools can be a
chore.[32]
In
SDK 1.1 and later, you get three classes that do all the hard work
for you. The java.util.Date
class encapsulates a
point in time. The
java.util.GregorianCalendar
class, which descends from the abstract
java.util.Calendar
,
translates
between a point in time and calendar
fields like month, day, and year. Finally, the
java.text.DateFormat
class knows how to generate
and parse string representations of dates and times.[33]
The separation of the Date
class and the
GregorianCalendar
class is analogous to having a
class representing temperature and a class that translates that
temperature to Celsius units. Conceivably, we could define other
subclasses of Calendar
, say
JulianCalendar
or
LunarCalendar
.
The default GregorianCalendar
constructor
creates an object that represents the
current time, as determined by the system clock:
GregorianCalendar now = new GregorianCalendar( );
Other constructors accept values to specify the point in time. In the first statement in the following code, we construct an object representing August 9, 1996; the second statement specifies both a date and a time, yielding an object that represents 9:01 a.m., April 8, 1997.
GregorianCalendar daphne = new GregorianCalendar(1996, Calendar.AUGUST, 9); GregorianCalendar sometime = new GregorianCalendar(1997, Calendar.APRIL, 8, 9, 1); // 9:01 AM
We can also create a GregorianCalendar
by setting
specific fields using
the
set( )
method. The
Calendar
class contains a torrent of constants
representing both calendar fields and field values. The first
argument to the set( )
method is a field constant;
the second argument is the new value for the field.
GregorianCalendar kristen = new GregorianCalendar( ); kristen.set(Calendar.YEAR, 1972); kristen.set(Calendar.MONTH, Calendar.MAY); kristen.set(Calendar.DATE, 20);
A
GregorianCalendar
is created in the default time zone.
Setting the time zone of the calendar is
as easy as obtaining the desired TimeZone
and
giving it to the GregorianCalendar
:
GregorianCalendar smokey = new GregorianCalendar( ); smokey.setTimeZone(TimeZone.getTimeZone("MST"));
To represent a GregorianCalendar
’s date as a
string,
first create a Date
object:
Date mydate = smokey.getTime( );
To create a string representing a point in time, create a
DateFormat
object and apply its format( )
method to a Date
object. Although DateFormat
itself is abstract, it
has several static (“factory”) methods that return useful
DateFormat
subclass instances. To get a default
DateFormat
, simply call getInstance( )
:
DateFormat plain = DateFormat.getInstance( ); String now = plain.format(new Date( )); // 4/12/00 6:06 AM
You can generate a date string or a
time string, or both, using the getDateInstance()
,
getTimeInstance()
, and
getDateTimeInstance( )
factory methods. The
argument to these methods describes what level of detail you’d
like to see. DateFormat
defines four constants
representing detail levels: they are SHORT
,
MEDIUM
, LONG
, and
FULL
. There is also a DEFAULT
,
which is the same as MEDIUM
. The following code
creates three DateFormat
instances: one to format
a date, one to format a time, and one to format a date and time
together. Note that getDateTimeInstance( )
requires two arguments: the first specifies how to format the date,
the second how to format the time:
// 12-Apr-00 DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT); // 9:18:27 AM DateFormat tf = DateFormat.getTimeInstance(DateFormat.DEFAULT); // Wednesday, April 12, 2000 9:18:27 o'clock AM EDT DateFormat dtf = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
We’re showing only how to create the
DateFormat
objects here; to actually generate a
String
from a date, you’ll need to call the
format( )
method of these
objects.
Formatting dates and times for other countries is just as easy.
Overloaded factory methods accept a Locale
argument:
// 12 avr. 00 DateFormat df = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.FRANCE); // 9:27:49 DateFormat tf = DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.GERMANY); // mercoledi 12 aprile 2000 9.27.49 GMT-04:00 DateFormat dtf = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, Locale. ITALY);
To
parse a string representing a date, we use the parse( )
method of the DateFormat
class. The
result is a Date
object. The parsing algorithms
are finicky, so it’s safest to parse dates and times that are
in the same format that is produced by the
DateFormat
. The parse( )
method
throws a
ParseException
if it doesn’t understand the string you give it. All of the
following calls to parse( )
succeed except the
last; we don’t supply a time zone, but the format for the time
is LONG
. Other exceptions are occasionally thrown
from the parse( )
method. To cover all the bases,
catch
NullPointerExceptions
and
StringIndexOutOfBoundsExceptions
,
also.
try { Date d; DateFormat df; df = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL); d = df.parse("Wednesday, April 12, 2000 2:22:22 o'clock PM EDT"); df = DateFormat.getDateTimeInstance( DateFormat.MEDIUM, DateFormat.MEDIUM); d = df.parse("12-Apr-00 2:22:22 PM"); df = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG); d = df.parse("April 12, 2000 2:22:22 PM EDT"); // throws a ParseException; detail level mismatch d = df.parse("12-Apr-00 2:22:22 PM"); } catch (Exception e) { ... }
[32] For a wealth of information about time and world time-keeping conventions, see http://tycho.usno.navy.mil, the U.S. Navy Directorate of Time. For a fascinating history of the Gregorian and Julian calendars, try http://www.magnet.ch/serendipity/hermetic/cal_stud/cal_art.htm.
[33] In Java 1.0.2, the Date
class performed all
three functions. In Java 1.1 and later, most of its methods have been
deprecated, so that the only purpose of the Date
class is to represent a point in time.
Get Learning Java now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.