Core JSTL[c] Mastering the JSP Standard Tag Library
8.1 Formatting and Parsing Numbers
Numbers are formatted differently for different locales; for example, the number 234,682.155 (formatted for U.S. English) is formatted as 234.682,155 in French and German. The <fmt:formatNumber> action lets you format numbers according to a specified locale; for example, the following code formats the number 234682.155 as 234,682.155 for U.S. English: <fmt:setLocale value='en-US'/> Number Formatted for U.S. English: <fmt:formatNumber value='234682.155'/> Notice that the preceding code uses the <fmt:setLocale> action to establish a locale for the <fmt:formatNumber> action because <fmt:formatNumber> does not have an attribute that lets you specify a locale. There are other ways to establish a locale for JSTL formatting actions; for example, you can nest formatting actions in a <fmt:bundle> action or set the FMT_LOCALE configuration setting in a business component. [1] We can modify the preceding code fragment to format the specified numeric value for the German locale by changing the value of the <fmt:setLocale> action, like this: [1] See "Determining a Formatting Locale" on page 352 for more information about how the JSTL formatting actions determine their locales. <fmt:setLocale value='de-DE'/> Number Formatted for German: <fmt:formatNumber value='234682.155'/> Besides numbers, <fmt:formatNumber> can also format currencies and percents. The following <fmt:formatNumber> attributes control how numbers, currencies, and percents are formatted: minIntegerDigits , maxIntegerDigits , minFractionDigits , maxFractionDigits , and groupingUsed ; for example: <fmt:setLocale value='en-US'/> <fmt:formatNumber value='234682.155' maxIntegerDigits='4' maxFractionDigits='2' groupingUsed='false'/> The output for the preceding code fragment is 4682.16 . Notice that <fmt:formatNumber> handles rounding automatically. That rounding is carried out in half-even mode by rounding to the nearest even number when the number is equidistant between two numbers; for example, 0.154 will round to 0.15 and 0.156 will round to 0.16, but 0.155, which is equidistant from 0.15 and 0.16, rounds to the nearest even number, which is 0.16. Every locale has a default pattern for numbers, currencies, and percents; for example, for U.S. English, numbers are formatted with this pattern: #,###. where # represents a digit, the comma represents a grouping separator, and the period represents a decimal separator. You can also specify custom patterns with the <fmt:formatNumber> pattern attribute, like this: <fmt:setLocale value='en-US'/> <fmt:formatNumber value='234682.155' pattern='#,####.00000'/> The output of the preceding code fragment is 23,4682.15500 because the pattern specifies a grouping of four integer digits and five fraction digits. See "Custom Number Patterns" on page 319 for more information about custom formatting patterns for numbers. The <fmt:formatNumber> action has a type attribute that lets you specify how <fmt:formatNumber> formats a number: as a number (the default), currency, or percent. For example, you can format a number as currency, like this: <fmt:formatNumber value='234682.155' type='currency'/> The preceding line of code formats the number 234682.155 as currency. If you set the locale to U.S. English, the output will be $234,682.16 . The <fmt:formatNumber> action also has currencyCode and currencySymbol attributes that control the currency symbol that <fmt:formatNumber> uses to format currencies. See "Currencies" on page 326 for more information about formatting currencies. You can also parse numbers, currencies, and percents with the <fmt:parseNumber> action; the following code fragment parses a number: <fmt:setLocale value='en-US'/> <fmt:formatNumber value='234682.155' var='formattedNumber'/> <fmt:parseNumber value='${formattedNumber}'/> By default, <fmt:formatNumber> sends its output to the current JspWriter , but if you specify the var attribute, <fmt:formatNumber> stores its output in a scoped variable whose name is specified with the var attribute. The <fmt:formatNumber> action stores scoped variables in page scope by default, but you can specify a different scope with the scope attribute. In the preceding code fragment, <fmt:formatNumber> stores the string 234,682.155 in a scoped variable named formattedNumber in page scope. Subsequently, <fmt:parseNumber> parses that string by specifying the formattedNumber scoped variable for its value attribute. The resulting output is the original numeric value: 234682.155 . Like <fmt:formatNumber>, <fmt:parseNumber> has a type attribute that specifies the type of value that it parses. Just like the type attribute for <fmt:formatNumber>, the <fmt:parseNumber> action's type attribute can be specified as number (the default), currency , or percent . For example, the following code fragment uses <fmt:parseNumber> to parse a currency: <c:set var='originalMonetaryAmount' value=',000'/> <fmt:parseNumber value='${originalMonetaryAmount}' var='parsedAmount' type='currency' parseLocale='en-US' /> <c:set var='result' value='${parsedAmount - 1000}'/> <fmt:setLocale value='en-US'/> <fmt:formatNumber value='${result}' type='currency'/> In the preceding code fragment, <fmt:parseNumber> parses a scoped variable as currency and stores the resulting numeric value in a scoped variable named parsedAmount . Subsequently, the <c:set> action subtracts 1000 from that amount and stores the resulting value in a scoped variable named result . Finally, <fmt:formatNumber> formats the value of the result scoped variable as U.S. currency. The resulting output of the preceding code fragment is $9,000 . In the preceding code fragment, the locale used by <fmt:parseNumber> is specified as U.S. English ( en-US ) because that's how the originalMonetaryAmount scoped variable is formatted. Unlike <fmt:formatNumber>, <fmt:parseNumber> provides an attribute ” parseLocale ”that lets you explicitly specify the locale that <fmt:parseNumber> uses to parse its value. [2] [2] The JSTL expert group felt that <fmt:formatNumber> had enough attributes, so in the interest of simplicity, <fmt:formatNumber> does not have an attribute for a locale. The locale that <fmt:parseNumber> uses must have the same formatting pattern and formatting symbols as the value that <fmt:parseNumber> parses; for example, if you change the parse locale in the preceding code fragment to fr-FR , <fmt:parseNumber> will throw an exception because the formatting pattern and symbols for the French locale don't match the value that <fmt:parseNumber> tries to parse. Like <fmt:formatNumber>, <fmt:parseNumber> has a pattern attribute that specifies a parsing pattern. Typically, that attribute is only used when a numeric value has been formatted with a custom pattern; for example, consider the following code fragment: <fmt:setLocale value='en-US'/> <c:set var='originalAmount' value='1,0,0,0.00'/> <fmt:parseNumber value='${originalAmount}' var='parsedAmount' pattern ='#,#.##'/> <c:set var='result' value='${parsedAmount - 100}'/> <fmt:formatNumber value='${result}'/> The preceding code fragment will print the value 900 . You can specify a wide variety of formatting and parsing patterns; see "Custom Number Patterns" on page 319 for more information about custom patterns. Figure 8-1 shows a JSP page that displays a numeric value formatted with <fmt:formatNumber>. That JSP page lets you modify most of the <fmt:formatNumber> action's attributes. In addition to illustrating how <fmt:formatNumber> works, the JSP page shown in Figure 8-1 represents somewhat of a lab for <fmt:formatNumber>; you can modify parameters to discover how <fmt:formatNumber> works for various combinations of attributes. Figure 8-1. Formatting Numbers
The JSP page shown in Figure 8-1 lets you modify the value that <fmt:formatNumber> formats and the locale that it uses. You can also modify the following <fmt:formatNumber> attributes: minIntegerDigits , maxIntegerDigits , minFractionDigits , maxFractionDigits , and groupingUsed . In the upper-left picture, those attributes are set to 1 , 10 , , 3 , and true , respectively. That picture shows a number formatted for the U.S. English (en-US) locale. In the upper-right picture in Figure 8-1, the German locale (de-DE) is used to format the numeric value with the same attribute settings as the upper-left picture. Notice that the formatting pattern for the German locale uses a period as the grouping separator and a comma as the decimal separator, which is the opposite of the U.S. English locale. The bottom pictures in Figure 8-1 set the minimum fraction digits to 8 , which causes the fractional component of the formatted value to be zero- padded to eight places. In the lower-left picture, the groupingUsed attribute for <fmt:formatNumber> is true , whereas that attribute is false in the lower-right picture. When the groupingUsed attribute is set to false , the grouping separator, which for the U.S. English locale is a comma, is not used. The JSP page shown in Figure 8-1 is listed in Listing 8.1. Listing 8.1 Formatting Numbers
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Formatting Numbers</title> </head> <body> <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %> <%@ taglib uri='http://java.sun.com/jstl/core_rt' prefix='c_rt' %> <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt'%> <%-- Check locale and value request parameters --%> <c:choose> <c:when test='${not empty param.locale}'> <c:set var='locale' value='${param.locale}'/> </c:when> <c:otherwise> <c_rt:set var='locale' value='<%= java.util.Locale.getDefault() %>'/> </c:otherwise> </c:choose> <c:choose> <c:when test='${not empty param.value}'> <c:set var='value' value='${param.value}'/> </c:when> <c:otherwise> <c:set var='value' value='12345.6789'/> </c:otherwise> </c:choose> <%-- <fmt:formatNumber> doesn't have a formatLocale attribute, so the locale is specified with <fmt:setLocale> --%> <fmt:setLocale value='${locale}'/> <%-- Format the number --%> <font size='5'> After Formatting: <fmt:formatNumber value='${value}' minIntegerDigits='${param.minIntDig}' maxIntegerDigits='${param.maxIntDig}' minFractionDigits='${param.minFrDig}' maxFractionDigits='${param.maxFrDig}' groupingUsed='${param.groupingUsed}'/> </font> <%-- Because this form does not specify an action, this JSP page will be reloaded when the form's submit button is activated --%> <form> <table> <tr> <td>Format this value:</td> <td><input type='text' value='<c:out value="${value}"/>' name='value'/> </td> </tr> <tr> <td>With this locale:</td> <td> <select name='locale'> <c_rt:forEach var='formatLocale' items='<%= java.text.NumberFormat. getAvailableLocales()%>'> <option <c:if test='${locale == formatLocale}'> selected </c:if> ><c:out value='${formatLocale}'/> </option> </c_rt:forEach> </select> </td> </tr> <tr> <td>Minimum Integer Digits:</td> <td> <select name='minIntDig'> <c:forEach items='0,1,2,3,4,5,6,7,8,9,10' var='minIntDig'> <option <c:if test='${param.minIntDig == minIntDig}'> selected </c:if> ><c:out value='${minIntDig}'/> </option> </c:forEach> </select> </td> </tr> <tr> <td>Maximum Integer Digits:</td> <td> <select name='maxIntDig'> <c:forEach items='0,1,2,3,4,5,6,7,8,9,10,40' var='maxIntDig'> <option <c:if test='${param.maxIntDig == maxIntDig}'> selected </c:if> ><c:out value='${maxIntDig}'/> </option> </c:forEach> </select> </td> </tr> <tr> <td>Minimum Fraction Digits:</td> <td> <select name='minFrDig'> <c:forEach items='0,1,2,3,4,5,6,7,8,9,10' var='minFrDig'> <option <c:if test='${param.minFrDig == minFrDig}'> selected </c:if> ><c:out value='${minFrDig}'/> </option> </c:forEach> </select> </td> </tr> <tr> <td>Maximum Fraction Digits:</td> <td> <select name='maxFrDig'> <c:forEach items='0,1,2,3,4,5,6,7,8,9,10,40' var='maxFrDig'> <option <c:if test='${param.maxFrDig == maxFrDig}'> selected </c:if> ><c:out value='${maxFrDig}'/> </option> </c:forEach> </select> </td> </tr> <tr> <td>Grouping Used:</td> <td> <select name='groupingUsed'> <c:forEach items='true,false' var='groupingUsed'> <option <c:if test='${param.groupingUsed == groupingUsed}'> selected </c:if> ><c:out value='${groupingUsed}'/> </option> </c:forEach> </select> </td> </tr> </table> <p><input type='submit'/> </form> </body> </html> The preceding JSP page begins by checking the locale and value request parameters, which are generated by the page's form. If those values have not been specified, they are set to default values: the JSP container's default locale for the locale parameter and 12345.6789 for the value parameter. Subsequently, the preceding JSP page sets the locale with the <fmt:setLocale> action and uses <fmt:formatNumber>, with the attributes specified in the form, to format the numeric value. The rest of the JSP page creates the form. The locale HTML select element is populated with the available locales for number formatting. Also, all of the select elements display their previously selected values by testing whether the currently enumerated option value is equal to the previously selected value for that element. Custom Number Patterns
As illustrated in "Formatting and Parsing Numbers" on page 310, you can format numeric values as numbers, currencies, or percents by specifying the <fmt:formatNumber> type attribute. When you specify that attribute, you are actually requesting a formatting pattern for a specific locale; for example, if you specify the type attribute as number for the U.S. English locale, you are requesting the pattern #,###. , which is the default number formatting pattern for that locale. You can further refine that locale-specific pattern with other <fmt:formatNumber> attributes, such as minIntegerDigits or maxFractionDigits . This section shows you how to specify custom formatting patterns that are independent of any locale. Because custom formatting patterns are independent of any locale, it's usually preferable to use the <fmt:formatNumber> type attribute in concert with the other formatting attributes, such as minIntegerDigits or maxFractionDigits , instead of custom patterns because the former uses locale-specific patterns automatically.
Note This section provides an overview of custom number patterns; see the Java documentation for the java.text.DecimalFormat class for a more in-depth treatment of this subject.
Custom formatting patterns are defined like this: [3] [3] That definition comes from the Java documentation for the java.text.DecimalFormat class, which uses the same syntax as the Java Language Specification. The subscript opt means optional. Pattern: PositivePattern PositivePattern ; NegativePattern PositivePattern: Prefix opt Number Suffix opt NegativePattern: Prefix opt Number Suffix opt Prefix: any Unicode characters except \uFFFE , \uFFFF , and special characters Suffix: any Unicode characters except \uFFFE , \uFFFF , and special characters Number: Integer Exponent opt Integer . Fraction Exponent opt Integer: MinimumInteger # # Integer # , Integer MinimumInteger: 0 0 MinimumInteger 0 , MinimumInteger Fraction: MinimumFraction opt OptionalFraction opt MinimumFraction: MinimumFraction opt OptionalFraction: # OptionalFraction opt Exponent: E MinimumExponent MinimumExponent: MinimumExponent opt Formatting patterns consist of a subpattern for positive numbers and an optional subpattern for negative numbers. Those subpatterns consist of an integer value that can contain one or more # or characters, in addition to an optional prefix, fraction pattern, and a suffix. A comma can appear within the integer portion of the pattern. Table 8.1 lists the symbols that you can use within a formatting pattern. From the preceding table, the most frequently used characters in custom formatting patterns are # , , the comma, and the period. Both the # and characters represent digits, but the character will fill with zeros if there is no corresponding digit for a given column, whereas nothing will be generated for a # character if there is no corresponding digit. For example, for the number 1.23 , the pattern #.#### will generate 1.23 , whereas the pattern 0.0000 will generate 1.2300 . Table 8.1. Number Pattern Symbols
You can use the # (or ) character and a comma to specify how digits should be grouped within a number; for example, for the number 123456789 , the pattern #,### will generate 123,456,789 . Only the rightmost group of # characters specify grouping; for example, the pattern #,## is equivalent to #,####,## and #,###########,## . For the number 123456789 , all three of the preceding patterns will generate 1,23,45,67,89 . You can also use the # (or ) character and a period to specify how the fractional portion of a number is formatted; for example, the pattern #.## specifies two digits after the decimal point, so if the number 123.456 is formatted with that pattern, the result will be 123.46 . Notice that rounding is automatically handled by the <fmt:formatNumber> action. Rounding mode is half-even; see "Formatting and Parsing Numbers" on page 310 for an explanation of that mode. Figure 8-2 shows a JSP page that lets you specify a numeric value, a locale, and a formatting pattern. That JSP page uses <fmt:formatNumber>, with the specified locale and formatting pattern to format the specified value. The top two pictures illustrate the difference between the # and characters, and the bottom picture shows what happens when you change locales. Figure 8-2. Formatting Numbers with Custom Patterns
As the top and bottom pictures in Figure 8-2 illustrate, the comma and period characters only specify placeholders for a locale's grouping separator and decimal separator, respectively. The same patterns are specified in the top and bottom pictures in Figure 8-2, but the formatting is different because the grouping and decimal separators for U.S. English and German are different. The JSP page shown in Figure 8-2 is listed in Listing 8.2. The preceding JSP page begins by checking the locale and value request parameters, which are generated by the page's form. If those parameters were not specified, scoped variables representing those parameters are set to default values: the JSP container's default locale for the locale parameter, and 1234567.4327 for the value parameter. Listing 8.2 Formatting Numbers with Custom Patterns
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Formatting Numbers With Patterns</title> </head> <body> <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %> <%@ taglib uri='http://java.sun.com/jstl/core_rt' prefix='c_rt' %> <%@ taglib uri='http://java.sun.com/jstl/fmt' prefix='fmt'%> <%-- Set values based on request parameters --%> <c:choose> <c:when test='${empty param.value}'> <c:set var='value' value='1234567.4327'/> </c:when> <c:otherwise> <c:set var='value' value='${param.value}'/> </c:otherwise> </c:choose> <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 --%> <fmt:setLocale value='${locale}'/> <%-- Show formatted number --%> <font size='5'> Formatted value: <fmt:formatNumber value='${value}' pattern='${param.pattern}'/> </font> <%-- Because this form does not specify an action, this JSP page will be reloaded when the form's submit button is activated --%> <form> <table> <tr> <td>Format this value:</td> <td><input type='text' name='value' value='<c:out value="${value}"/>'/> </td> </tr> <tr> <td>With this locale:</td> <td> <select name='locale'> <c_rt:forEach var='thisLocale' items='<%= java.text.NumberFormat. 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' value='<c:out value="${param.pattern}"/>'/> </td> </tr> </table> <p><input type='submit'/> </form> </body> </html> The preceding JSP page subsequently sets the locale for the <fmt:formatNumber> action and uses that action, with the specified formatting pattern, to format the specified value. The rest of the JSP page creates the form. You can use the preceding JSP page to experiment with formatting patterns and locales for various numeric values. Percents
The <fmt:formatNumber> action lets you format percents in addition to numbers and currencies by specifying percent for the <fmt:formatNumber> action's type attribute, like this: <fmt:setLocale value='en-US'/> <fmt:formatNumber value='0.234778' type='percent'/> When formatting percents, <fmt:formatNumber> multiplies the specified value by 100 and adds a locale-sensitive percent symbol; for example, the preceding code fragment produces this output: 23% . [4] [4] The percent symbol ” % ”is nearly universal and is usually displayed after the number. By default, <fmt:formatNumber> does not show any fraction digits for percents, as you can see from the output of the preceding code fragment; however, you can force <fmt:formatNumber> to display those digits if you specify the minFractionDigits attribute, like this: <fmt:formatNumber value='0.234778' type='percent' minFractionDigits='3'/> The output of the preceding code fragment is 23.478% . You can also specify any of the other <fmt:formatNumber> attributes when you format percents; [5] for example, you could do this: [5] The exception is the pattern attribute, because the pattern and type attributes are mutually exclusive. <fmt:setLocale value='en-US'/> <fmt:formatNumber value='0.234778' type='percent' minIntegerDigits='6' minFractionDigits='7'/> The output of the preceding code fragment is 000,023.4778000% . If you change the locale to German ( de-DE ), <fmt:formatNumber> will use the grouping and decimal separators for that locale; for example, for the preceding use of <fmt:formatNumber> with the de-DE locale, you will get this output: 000.023,4778000% Additionally, you can also specify the <fmt:formatNumber> action's groupingUsed attribute to control whether the grouping separator symbol is used, although it's rarely specified in practice. Currencies
You can format currencies in a locale-dependent manner by setting the <fmt:formatNumber> type attribute to currency ; for example, here's a code fragment that formats currency for the United States: <fmt:setLocale value='en-US'/> <fmt:formatNumber value='0.234778' type='currency'/> The preceding code fragment will produce this output: $0.23 . By simply changing the locale used by <fmt:formatNumber>, you can format currencies for a different locale; for example, you can format currency for the euro, like this: [6] [6] You must use the ISO-8859-15 or UTF-8 charsets to display the euro. On Windows , the windows -1252 charset should also correctly display the euro symbol. <fmt:setLocale value='fr-FR'/> <fmt:formatNumber value='0.234778' type='currency'/> The preceding code fragment will only display the euro currency symbol if you are using JDK 1.4 (or higher). If you are using an older version of the Java Development Kit (JDK), you can specify the EURO locale variant, like this: <fmt:setLocale value='fr-FR' variant='EURO'/> <fmt:formatNumber value='0.234778' type='currency'/> The <fmt:formatNumber> action provides two attributes that you can use to explicitly control the currency symbol: currencySymbol and currencyCode ; for example, you can override the default currency symbol for France, like this: <fmt:setLocale value='fr-FR'/> <fmt:formatNumber value='0.234778' type='currency' currencySymbol ='$'/> Instead of displaying the euro symbol, the preceding code fragment produces this output: 0,23 $ . Notice that we formatted the currency symbol for the preceding code fragment for the French locale by placing it after the number; however the default currency symbol for that locale is overridden with the $ character. As you can see from the preceding code fragment, the <fmt:formatNumber> currencySymbol attribute lets you specify the currency symbol directly. You can also use the <fmt:formatNumber> currencyCode attribute to indirectly specify the currency symbol; for example, the following code fragment uses the currencyCode attribute to specify the Australian dollar symbol for Australian currency: <fmt:setLocale value='en-AU'/> <fmt:formatNumber value='0.234778' type='currency' currencyCode ='AUD'/> The output of the preceding code fragment is $0.23 . The <fmt:formatNumber> action uses the JDK to translate the currency code to the proper currency symbol; for the preceding code fragment, the JDK translates the currency code AUD ”for the en-AU locale ”to the $ currency symbol. When you specify a currency code, the actual currency symbol displayed can vary, depending upon the formatting locale; for example, the preceding code fragment uses the $ currency symbol for Australian dollars when the locale is en-AU (Australian English), but consider the following code fragment: <fmt:setLocale value=' en-US '/> <fmt:formatNumber value='0.234778' type='currency' currencyCode=' AUD '/> The preceding code fragment is identical to the previous code fragment, except for the formatting locale, which in this case is en-US (U.S. English). If the currency symbol displayed for the preceding code fragment was the same as the currency symbol displayed for the Australian locale ( $ ), there would be no way to distinguish between U.S. and Australian currency, so the preceding code fragment uses the currency code AUD to make that distinction. The output of the preceding code fragment is AUD0.23 . Currency codes are a new addition to the 1.4 version of the JDK, so the <fmt:formatNumber> currencyCode attribute is only supported if you are using JDK 1.4 (or a later version). If you specify both the currencySymbol and currencyCode attributes, currencyCode will take precedence over currencySymbol if you are using JDK 1.4 (or later); however, if you are using JDK 1.3 (or an earlier version), the currencySymbol attribute will take precedence over the currencyCode attribute. Currency codes are preferable to currency symbols because the JDK produces a currency symbol that's correct for the formatting locale, as the two preceding code fragments illustrate. For example, in the preceding code fragment, because the currency symbol for Australian dollars is $ , you might be tempted to specify that currency symbol instead of the AUD currency code. But because the formatting locale is U.S. English, that currency symbol would be ambiguous, so it's better to specify a currency code (in this case AUD ) and let the JDK select an unambiguous currency symbol for the formatting locale. Finally, the JDK currently has few localized currency symbols, but it may provide more in the future. Currency codes are defined by ISO 4217; Table 8.2 lists some examples of those currency codes. Table 8.2. Examples of Currency Codes [a]
[a] The French franc and German deutsche mark have been replaced by the euro. For a complete list of ISO 4217 currency codes, see the following URL: http://www.bsi-global.com/Technical+Information/Publications/_Publications/tig90x.doc The JSP page shown in Figure 8-3 uses the <fmt:formatNumber> currencyCode to display formatted currencies for the countries listed in Table 8.2. [7] [7] The grouping separator for the fr-FR locale is a period, but that character is a space in Figure 8-3 and Figure 8-4 because of a JDK 1.4 bug. Figure 8-3. Formatting Currencies (font is enlarged to clearly show currency symbols)
The JSP page shown in Figure 8-3 is listed in Listing 8.3. The preceding JSP page uses the UTF-8 charset to properly display all of the currency symbols. [8] If you don't use a charset that can display the currency symbol for a given locale, that currency symbol will not be properly displayed; for example, if you don't specify the UTF-8 charset for the preceding JSP page, you will get the result shown in Figure 8-4. [9] [8] See "Unicode and Charsets" on page 260 for more information about the UTF-8 charset. [9] Figure 8-4 shows the JSP page displayed by Tomcat 4.0.3; results may vary for other servlet containers. Figure 8-4. Formatting Currencies with the Wrong Charset
Listing 8.3 Formatting Currencies with <fmt:formatNumber>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Formatting Currencies</title> </head> <body> <%-- Use the UTF-8 charset for multiple languages--%> <%@ 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'%> <c:set var='number' value='456789.1234'/> <font size='5'> <c:out value='Formatting this number: ${number}'/> </font> <p><table border='1'> <tr> <th><font size='5'>Country</font></th> <th><font size='5'>Formatted Currency</font></th> </tr> <tr><td><font size='5'>France (EURO)</font></td> <fmt:setLocale value=' fr-FR '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' EUR '/></font></td> </tr> <tr><td><font size='5'>France (French Franc)</font></td> <fmt:setLocale value=' fr-FR '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' FRF '/></font></td></tr> <tr><td><font size='5'>Germany (EURO)</font></td> <fmt:setLocale value=' de-DE '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' EUR '/></font></td></tr> <tr><td><font size='5'>Germany (Deutsche Mark)</font></td> <fmt:setLocale value=' de-DE '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' DEM '/></font></td></tr> <tr><td><font size='5'>Great Britain</font></td> <fmt:setLocale value=' en-GB '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' GBP '/></font></td></tr> <tr><td><font size='5'>Israel</font></td> <fmt:setLocale value=' he-IL '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' ILS '/></font></td></tr> <tr><td><font size='5'>Japan</font></td> <fmt:setLocale value=' ja-JP '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' JPY '/></font></td></tr> <tr><td><font size='5'>Poland</font></td> <fmt:setLocale value=' pl-PL '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' PLN '/></font></td></tr> <tr><td><font size='5'>United States</font></td> <fmt:setLocale value=' en-US '/> <td><font size='5'> <fmt:formatNumber value='${number}' type='currency' currencyCode=' USD '/></font></td></tr> </table> </body> </html> If you don't use the UTF-8 charset, you must specify a charset that corresponds to the currency symbol that you are trying to display; for example, if you want to display the New Israel Sheqel currency symbol, you can use the ISO-8859-8 charset, and if you want to display the euro currency symbol, you can use the ISO-8859-15 charset. Table 8.3 lists some example currency symbols and their corresponding charsets. For a complete list of Latin charsets and their corresponding countries, see the following URL: http://wwwwbs.cs.tu-berlin.de/ user /czyborra/charsets Table 8.3. Examples of Currency Symbols and Corresponding Charsets
|