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
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]
[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.
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
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> |