Core JSTL[c] Mastering the JSP Standard Tag Library

   

Like numbers , dates are formatted differently for different locales; for example, the date May 9, 2002 is formatted (in short form) as 5/9/02 for the U.S. English ( en-US ) locale and as 09/05/02 for the France French ( fr-FR ) locale. JSTL provides two actions, <fmt:formatDate> and <fmt:parseDate>, that format and parse dates, respectively.

The <fmt:formatDate> action formats an instance of java.util.Date and outputs a string representation of that date. The three most common ways to create a date for <fmt:formatDate> are with <jsp:useBean>, <fmt_rt:formatDate>, or <fmt:parseDate>; for example, you can create a date with <jsp:useBean> like this:

<fmt:setLocale value='en-US'/> <jsp:useBean id='today' class='java.util.Date'/> <fmt:formatDate value='${today}'/>

In the preceding code fragment, the <jsp:useBean> action stores an instance of java.util.Date (which represents the current date) in a scoped variable named today in page scope. Subsequently, the <fmt:formatDate> action accesses that scoped variable and formats it according to the U.S. English locale. If the current date is the 9th of May in the year 2002, the output of the preceding code fragment will be May 9, 2002 . If you change the locale specified with the <fmt:setLocale> action in the preceding code fragment to fr-FR , the output of the preceding code fragment will be 9 mai 2002 .

You can also use the <fmt_rt:formatNumber> action to format an instance of java.util.Date that's created with a JSP expression, like this:

<fmt:setLocale value='en-US'/> <fmt_rt:formatDate value='<%= new java.util.Date() %>'/>

The preceding code fragment is functionally identical to the code fragment listed above that uses the <jsp:useBean> action.

The <fmt:parseDate> action parses a string into an instance of java.util.Date , so you can use <fmt:parseDate> in concert with <fmt:formatDate> to format a string representation of a date, like this:

<fmt:setLocale value='en-US'/> <fmt:parseDate value='May 9, 2002' var=' date '/> <fmt:formatDate value=' ${date} ' dateStyle=' short '/>

In the preceding code fragment, <fmt:parseDate> parses the string May 9, 2002 and stores the resulting java.util.Date instance in a scoped variable named date in page scope. Subsequently, the <fmt:formatDate> action accesses that scoped variable and formats the date with the short date style as 5/9/02 .

The <fmt:formatDate> and <fmt:parseDate> actions can format and parse, respectively, a date, a time, or both. By default, those actions format and parse a date, but you can specify just the time or both the date and the time with the <fmt:formatDate> and <fmt:parseDate> type attributes; for example, you can format both the date and time like this:

<fmt:setLocale value='en-US'/> <jsp:useBean id='today' class='java.util.Date'/> <fmt:formatDate value='${today}' type='both' />

Assuming a current date and time of May 9, 2002 at 2:36:53 P.M., the preceding code produces the following output for the U.S. English locale: May 9, 2002 2:36:53 PM . If you set the <fmt:formatDate> type attribute to time , the preceding code fragment will produce this output for the U.S. English locale: 2:36:53 PM .

Dates and times can be formatted (and parsed) with predefined formats, which are specified with the <fmt:formatDate> (and <fmt:parseDate>) dateStyle and timeStyle attributes. Valid values for those attributes are default , short , medium , long , and full , where default is the same as medium . The default value is used if the dateStyle and timeStyle attributes are not specified.

Examples of those predefined formats are shown in Table 8.4.

Table 8.4. Predefined Date and Time Formats

Value

Description

Example Date and Time for U.S. Locale

short

Numeric

10/19/00 6:07 PM

medium

Longer than short

Oct 19, 2000 6:07:01 PM

long

Longer than medium

October 19, 2000 6:07:01 PM MDT

full

Completely specified

Thursday, October 19, 2000 6:07:01 PM MDT

It's also easy to format dates and times for non-Latin languages; for example, here's how you'd format the current date and time for Chinese, Arabic, and Thai, all in the same JSP page:

<%-- Use UTF-8 to display multiple languages --%> <%@ page contentType='text/html; charset=UTF-8' %> <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt' %> <%-- Chinese, Taiwan --%> <fmt:setLocale value=' zh-TW '/> <fmt_rt:formatDate value='<%= new java.util.Date() %>' type='both' dateStyle='full' timeStyle='full'/> <p> <%-- Arabic, Saudi Arabia --%> <fmt:setLocale value=' ar-SA '/> <fmt_rt:formatDate value='<%= new java.util.Date() %>' type='both' dateStyle='full' timeStyle='full'/> </p><p> <%-- Thai, Thailand --%> <fmt:setLocale value=' th-TH '/> <fmt_rt:formatDate value='<%= new java.util.Date() %>' type='both' dateStyle='full' timeStyle='full'/> </p>

Here's what the preceding code fragment produces for the 25th of May, 2002 at 2:17:17 PM, EDT:

If the predefined formats listed in Table 8.4 are not sufficient, you can specify custom formatting patterns for both the <fmt:formatDate> and <fmt:parseDate> actions. Those custom formatting patterns are discussed in "Custom Patterns for Dates and Times" on page 336.

You can also specify a time zone for <fmt:formatDate> and <fmt:parseDate> with the timeZone attribute. That attribute comes in handy when a Web server resides in one time zone and clients reside in another; for example, the following code fragment formats the current date and time for the America/Denver time zone:

<fmt:setLocale value='en-US'/> <jsp:useBean id='today' class='java.util.Date'/> <fmt:formatDate value='${today}' type='both' timeZone='America/Denver' timeStyle='full'/>

In the preceding code fragment, the timeStyle attribute for the <fmt:formatDate> action is specified as full , so the time zone will be displayed. If the current date and time is May 9, 2002 at 3:16:13 PM, the output of the preceding code fragment will be:

May 9, 2002 3:16:13 PM MDT

In addition to the <fmt:formatDate> and <fmt:parseDate> timeZone attributes, you can also specify time zones with the <fmt:timeZone> and <fmt:setTimeZone> actions, which are discussed in "Using Time Zones" on page 343.

Custom Patterns for Dates and Times

If the predefined date and time patterns ”see Table 8.4 ”are not sufficient for your needs, you can specify custom date and time patterns; for example, the following code fragment formats the current date and time according to a custom pattern:

<jsp:useBean id='now' class='java.util.Date'/> <fmt:formatDate value='${now}' type='both' pattern="MM/dd/yyyy' at: 'hh:mm:ss"/>

The preceding code fragment formats the current date and time using the pattern MM/dd/yyyy' at: 'hh:mm:ss . Assuming a current date and time of May 11, 2002 at 10:43:53, the preceding code fragment will produce the following output: 05/11/2002 at: 10:40:53 . All characters within a custom date pattern are interpreted by the <fmt:formatDate> and <fmt:parseDate> actions, except for characters enclosed in single quotes. In the preceding code fragment, the quoted string ' at: ' is not interpreted.

You can also use custom date patterns to parse a string representation of a date with <fmt:parseDate>, like this:

<fmt:parseDate value='6/20/1957' var='parsedDate' pattern='MM/dd/yyyy'/> <fmt:formatDate value='${parsedDate}' pattern="MMMM dd'th, 'yyyy' was a 'EEEE"/>

In the preceding code fragment, <fmt:parseDate> parses the string 6/20/1957 using the pattern MM/dd/yyyy and stores the resulting instance of java.util.Date in a scoped variable named parsedDate . Subsequently, <fmt:formatDate> formats that date with another custom date pattern. The output of the preceding code fragment is June 20th, 1957 was a Thursday .

You should note that patterns specified for <fmt:parseDate> must match the string that <fmt:parseDate> parses; for example, consider the following code fragment:

<fmt:parseDate value='20/6/1957' pattern='MM/dd/yyyy'/>

In the preceding code fragment, <fmt:parseDate> will throw an exception because 20 is not a valid numeric value for a month, even though the pattern MM/dd/yyyy is valid for many locales.

Table 8.5 lists the characters you can use in a custom date pattern.

Table 8.5. Characters Used in Date and Time Patterns [a]

Letter

Date or Time Component

Presentation

Examples

G

Era designator

Text

AD

y

Year

Year

2002 02

M

Month in year

Month

August Aug 08

w

Week in year

Number

50

W

Week in month

Number

3

D

Day in year

Number

224

d

Day in month

Number

20

F

Day of week in month

Number

6

E

Day in week

Text

Wednesday Wed

a

Am/pm marker

Text

AM PM

H

Hour in day (0-23)

Number

k

Hour in day (1-24)

Number

24

K

Hour in am/pm (0-11)

Number

h

Hour in am/pm (1-12)

Number

12

m

Minute in hour

Number

50

s

Second in minute

Number

55

S

Millisecond

Number

960

z

Time zone

General time zone

Pacific Standard Time PST GMT-08:00

Z

Time zone

RFC 822 time zone

0800

[a] This table and the related discussion that follows is derived from the Java documentation for the java.text.SimpleDateFormat class.

The letters listed in the preceding table are usually specified in multiples ; the number of times a letter is repeated determines presentation as follows, where each heading (such as Text, Number, etc.) corresponds to the Presentation column from the preceding table: [10]

[10] All of the following examples assume an en-US locale.

  • Text:

    • Formatting : If you specify 4 or more letters, a full format is used; otherwise , an abbreviated form is used if available. For example, for Sunday, the patterns E, EE, and EEE will display Sun , whereas the pattern EEEE will display Sunday .

    • Parsing : Both the full and abbreviated forms are accepted, independently of the number of pattern letters.

  • Number:

    • Formatting : No matter how many letters you specify, the minimum number of digits is always shown; for example, if the day of the year is 125, that value will be displayed for D, DD, and DDD. If you specify more letters than the minimum number of digits, the number is zero- padded ; for example, if the day of the year is 125 and you specify DDDD , then 0125 will be displayed.

    • Parsing : The number of letters is ignored unless it's needed to separate adjacent fields.

  • Month:

    • Formatting : If the number of letters is less than 3, the month is interpreted as a Number; otherwise, it's interpreted as Text. For example, for the month of May, M and MM will display 5 and 05 , respectively, whereas MMM will display May .

    • Parsing : Same as formatting.

  • Year:

    • Formatting : If the number of letters is less than 4, the year is truncated to two digits; for example, for the year 2002, y , yy , and yyy will all display 02 , whereas yyyy will display 2002 .

    • Parsing : If the number of letters is more than 2, the year is interpreted literally; for example, for the pattern MM/dd/yyyy , the string 01/11/12 will be parsed as January 11, 12 AD . For an abbreviated year pattern ” y or yy ”the year is interpreted relative to the time span into which it falls . A 100-year time span is split into two parts arranged around the current date as follows: one part spans the past 80 years , and the other spans the next 20 years. Given an abbreviated year, the time span into which the year falls is determined, and the century information is taken from that time span. For example, for a parsing action used on January 1, 1997 , the string 01/11/12 would be parsed as January 11, 2012 , because 2012 falls into the time span 1997 + 20 years and 1912 does not fall into the time span 1997 - 80 years; and the string " 05/04/64 " would be parsed as May 4, 1964 because 1964 falls into the time span 1997 - 80 years and 2064 does not fall into the time span 1997 + 20 years.

  • General time zone:

    • Formatting : Time zones specified with a name , such as America/Denver , are interpreted as Text. You can also specify a time zone as a GMT offset, such as GMT-02:00 or GMT+03:30 .

    • Parsing : Same as formatting, except RFC 822 time zones are also accepted.

  • RFC 822 time zone: [11]

    [11] See http://www.ietf.org/rfc/rfc0822.txt?number=822 for more information about RFC 822.

    • Formatting : A 4-digit time zone format, such as 0700 .

    • Parsing : Same as formatting, except general time zones are also accepted.

Table 8.6 lists some example date and time patterns for the U.S. English locale.

Table 8.6. Date and Time Pattern Examples for U.S. English

Pattern

Result

MM/dd/yyyy

05/06/2002

h 'o''clock and' mm 'minutes'

2 o'clock and 36 minutes

'Today is: 'EEEE, MMM dd

Today is Monday, May 06

h:mm a, z

2:36 AM, MST

E, MMM d'th at precisely:' hh:mm:ss:

Mon, May 6th at precisely: 02:36:27:497

'It''s' yyyy G

It's 2002 AD

k:m:s, dd/MM ''yy Z

14:36:27, 06/05 '02 -0600

The example patterns in the preceding table use a wide range of the characters listed in Table 8.5, including the characters for time zones and milliseconds . Notice that two consecutive single quotes in a row produce one single quote in the output.

Figure 8-5 shows a JSP page that you can use to specify a locale and a custom date pattern to format the current date. The top picture in Figure 8-5 shows a pattern that generates a fairly complete date format, and the bottom picture shows a pattern that generates a short date format with the year fully specified.

Figure 8-5. Formatting Dates with Custom Patterns

The JSP page shown in Figure 8-5 is listed in Listing 8.4.

The preceding JSP page lets you select a locale from any of the available locales that the JDK uses to format dates, by calling java.text.DateFormat.getAvailableLocales() . Because you can select from so many different locales, the preceding JSP page uses the UTF-8 charset. See "Unicode and Charsets" on page 260 for more information about that charset.

After setting the charset, the preceding JSP page creates a scoped variable for the previously selected locale. If no locale was selected, the JSP page sets that scoped variable to the default locale. The JSP page uses that scoped variable to set the locale with <fmt:setLocale> and also to select the previously selected locale for the HTML select element that displays available locales for date formatting. Subsequently, the JSP page creates a scoped variable named now with <jsp:useBean> and uses <fmt:formatDate> to format that date with the specified pattern. The rest of the JSP page creates the form.

Listing 8.4 Formatting Dates with Custom Patterns

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Formatting Dates With Patterns</title> </head> <body> <%@ page contentType='text/html; charset=UTF-8' %> <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %> <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt'%> <%@ taglib uri='http://java.sun.com/jstl/core_rt' prefix='c_rt' %> <%-- Create a scoped variable based on the locale request parameter --%> <c:choose> <c:when test='${empty param.locale}'> <c_rt:set var='locale' value='<%= java.util.Locale.getDefault() %>'/> </c:when> <c:otherwise> <c:set var='locale' value='${param.locale}'/> </c:otherwise> </c:choose> <%-- Set the locale according to the locale request parameter --%> <fmt:setLocale value='${locale}'/> <%-- Create a scoped variable that contains the current date --%> <jsp:useBean id='now' class='java.util.Date'/> <%-- Show formatted number --%> <font size='5'>Formatted date: <c:choose> <c:when test='${not empty param.pattern}'> <fmt:formatDate value='${now}' pattern='${param.pattern}'/> </c:when> <c:otherwise> <fmt:formatDate value='${now}'/> </c:otherwise> </c:choose> </font> <%-- Because this form does not specify an action, this JSP page will be reloaded when the submit button is activated --%> <form> <table> <tr> <td>Format this date:</td> <td><c:out value='${now}'/></td> </tr> <tr> <td>With this locale:</td> <td> <select name='locale'> <c_rt:forEach var='thisLocale' items='<%= java.text.DateFormat. getAvailableLocales()%>'> <option <c:if test='${locale == thisLocale}'> selected </c:if> <c:out value='>${thisLocale}' escapeXml='false'/> </option> </c_rt:forEach> </select> </td> </tr> <tr> <td>With this pattern:</td> <td><input type='text' name='pattern' size='50' value='<c:out value="${param.pattern}"/>'/> </td> </tr> </table> <p><input type='submit'/> </form> </body> </html>

   

Категории