1.13. Formatting Dates

Problem

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.

Solution

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"

Discussion

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

ISO_DATE_FORMAT

yyyy-MM-dd"2004-01-02"

ISO_DATE_TIME_ZONE_FORMAT

yyyy-MM-ddZZ"2004-01-02-07:00"

ISO_DATETIME_FORMAT

yyyy-MM-dd'T'HH:mm:ss"2004-01-02T23:22:12"

ISO_DATETIME_TIME_ZONE_FORMAT

yyyy-MM-dd'T'HH:mm:ssZZ"2004-01-02T21:13:45-07:00"

ISO_TIME_FORMAT

'T'HH:mm:ss"T04:23:22"

ISO_TIME_NO_T_FORMAT

HH:mm:ss"05:12:34"

ISO_TIME_NO_T_TIME_ZONE_FORMAT

HH:mm:ssZZ"12:32:22-07:00"

ISO_TIME_TIME_ZONE_FORMAT

'T'HH:mm:ssZZ"T18:23:22-07:00"

SMTP_DATETIME_FORMAT

EEE, dd MMM yyyy HH:mm:ss Z"Wed, 01 Feb 2004 20:03:01 CST"

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.

See Also

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 Jakarta 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.

Get Jakarta Commons Cookbook 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.