Formatting and Parsing Messages – Localization
By Gigi Rosen / June 24, 2024 / No Comments / Compact Number Parsing, Oracle Certifications
18.7 Formatting and Parsing Messages
A compound message may contain various kinds of data: strings, numbers, currencies, percentages, dates, and times. The locale-sensitive values in such messages should be formatted according to an appropriate locale. In this section we first consider a solution provided by the java.text.MessageFormat class for formatting compound messages. Later we consider the java.text.ChoiceFormat class that supports conditional formatting (p. 1145).
An overview of various other support in the Java SE APIs for formatting compound messages can be found at the end of this section (p. 1152).
Format Patterns
The modus operandi of formatters provided by the MessageFormat class is a classic one, as exemplified by the printf() method called on the System.out static field (ยง1.9, p. 24). A string pattern designating placeholders for values is specified. MessageFormat takes a list of values and formats them, and then inserts their text representation into the respective placeholders in the pattern to create the final result. The simple example below illustrates the basic use of the MessageFormat class.
String pattern = “At {3} on {2} Elvis landed at {0} and was greeted by {1} fans.”;
String output = MessageFormat.format(pattern, “Honolulu”, 3000,
LocalDate.of(1961,3,25), LocalTime.of(12,15));
System.out.println(output);
Output from the code:
At 12:15 on 1961-03-25 Elvis landed at Honolulu and was greeted by 3,000 fans.
The pattern specifies placeholders (called format elements) using curly brackets {} to designate where text representations of values are to be inserted. The number specified in a format element is the argument index of a particular argument in the list of arguments submitted to the formatter. In the code above, the pattern has four format elements.
The variable arity static method MessageFormat.format() is passed the pattern and a list of arguments to format. Below, we can see which argument in the method call is indicated by the argument index in a format element that is specified in the pattern above.
Format element: {0} {1} {2} {3}
Arguments: “Honolulu”, 3000, LocalDate.of(1961,3,25), LocalTime.of(12,15)
Care must be taken that an argument index in a format element designates the right argument. The same argument index in multiple format elements just means that the argument it designates is applied to all of those format elements.
Note that the text outside of the format elements is copied verbatim to the result string. A single quote (‘) can be used to quote arbitrary characters, and two single quotes (”) can be used to escape a single quote in a pattern. For example, the pattern “‘{1}'” represents the string “{1}”, and not a format element.
The flexibility of the MessageFormat class will become clear as we dig into its functionality.
The general syntax of a format element is shown below:
{
Argument_Index
}
{
Argument_Index
,
Format_Type
}
{
Argument_Index
,
Format_Type
,
Format_Style
}
The format type and the format style allow further control over the formatting. The format type indicates what kind of argument (e.g., number, date, or time) is to be formatted, and the format style indicates how the argument will be formatted (e.g., currency format for a number, short format for a date). Legal combinations of format type and format style are shown in Table 18.16.
Table 18.16 Format Type and Format Style Combinations for Format Elements
Format type value | Format style value that can be specified for a format type |
none | none |
number | none, integer, currency, percent, subformat pattern |
date or time | none, short, medium, long, full, subformat pattern |
choice (p. 1145) | subformat pattern |
The first variant of the format element (first row in Table 18.16) was used in the code earlier, where neither format type nor format style is specified. In this case, the text representation of the argument as defined by the toString() method is used in the pattern to create the final result. We will explore other combinations from Table 18.16 in this section.
When format type and format style values are used in a format element, an appropriate formatter is implicitly created to format the argument corresponding to that particular format element. The formatters created are instances of the formatter classes shown in Figure 18.1, p. 1115. For example, the format element {3,time,short} results in a locale-specific formatter being created implicitly by the following method call:
DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())