You need to format a date, and SimpleDateFormat
is not thread-safe. You are
also looking for standard International Organization of Standards (ISO)
date formats.
Use FastDateFormat
, a
thread-safe formatter for Java Date
objects, and use public static instances of FastDateFormat
on DateFormatUtils
, which correspond to ISO date
and time formatting standards defined in ISO 8601. The following example
outputs the international standard for representing a date and time in a
given time zone:
Date now = new Date( ); String isoDT = DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( now ); System.out.println( "It is currently: " + isoDT );
This produces the following output displaying the current time with time-zone information:
It is currently: 2004-03-26T16:20:00-07:00
If you need to use a custom date format, use FastDateFormat
as a substitute for SimpleDateFormat
:
// create a formatter that simply prints the year and month FastDateFormat formatter = new FastDateFormat( "yyyy-mm", TimeZone.getDefault( ), Locale.getDefault( ) ); String output = formatter.format( new Date( ) ); // output equals "2003-10"
The problem for this recipe is two-fold; your multithreaded application needs to print out
standard date/time formats. Printing a
standard format is a problem easily solved by static instances of
FastDateFormat
on DateFormatUtils
. Ideally, every program that
needs to deal with dates knows how to recognize an ISO 8601 date when
parsing input. The world is getting smaller by the day; use
international standards when presenting dates, times, measures, and
country codes.
SimpleDateFormat
is incapable
of producing an ISO-8601-compliant time zone that matches the pattern:
+11:30
. Sun's SimpleDateFormat
class can generate time zones
without the colon separator, but these are incompatible with systems
that need to be able to parse a standard format. FastDateFormat
has achieved compliance with
the ISO 8601 standard by adding a "ZZ" date format symbol, which is
translated into the appropriate time-zone representation. In addition to
the format demonstrated in the previous example, the DateFormatUtils
class maintains a number of
variations on the full ISO 8601 date format; there is a format to show
only the time, a format to show only the date, and others, as well as
the standard format for displaying dates in Simple Mail Transfer
Protocol (SMTP). (See Table
1-4.)
Table 1-4. Static date/time formats in DateFormatUtils
Name |
Format |
---|---|
|
|
|
|
|
|
|
|
|
' |
|
|
|
|
|
' |
|
|
Why would you want to use FastDateFormat
in the same way SimpleDateFormat
is used? Isn't SimpleDateFormat
enough? The simple answer is
no; SimpleDateFormat
is
not thread-safe and FastDateFormat
is. In fact, you should be
aware that none of the Sun formatting classes are thread-safe. If
multiple threads are using any Java formatting object there is a
possibility of deadlock, RuntimeException
, or inconsistent behavior. If
your systems use a shared instance SimpleDateFormat
across multiple threads, you
should migrate to FastDateFormat
immediately.
Java date and time classes have a number of issues—concurrency issues with date formatting being "only the tip of the iceberg." An active member of the Commons community, Stephen Colebourne, has taken time to create a clean room reimplementation of a date and time API. For more information about Joda, take a look at the Joda project page (http://www.joda.org/).
For more information about the ISO date and time standards, see http://www.cl.cam.ac.uk/~mgk25/iso-time.html.
For more information about nonthread-safe implementations of
SimpleDateFormat
, see Sun's Bug Database, and look for Bug #4264153. Sun
specifically states that all of the format classes Format
, MessageFormat
, NumberFormat
, DecimalFormat
, ChoiceFormat
, DateFormat
, and SimpleDateFormat
are not thread-safe. It is
unclear if Sun has addressed this issue in Java 1.4, but if you are
writing critical multithreaded applications, you should avoid Sun's
formatting classes or synchronize access to them.