Skip to content

Commit f60798a

Browse files
author
Justin Lu
committed
8329222: java.text.NumberFormat (and subclasses) spec updates
Reviewed-by: naoto
1 parent 2555166 commit f60798a

File tree

3 files changed

+392
-362
lines changed

3 files changed

+392
-362
lines changed

src/java.base/share/classes/java/text/CompactNumberFormat.java

Lines changed: 117 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -47,112 +47,149 @@
4747
/**
4848
* <p>
4949
* {@code CompactNumberFormat} is a concrete subclass of {@code NumberFormat}
50-
* that formats a decimal number in its compact form.
51-
*
52-
* The compact number formatting is designed for the environment where the space
53-
* is limited, and the formatted string can be displayed in that limited space.
54-
* It is defined by LDML's specification for
50+
* that formats a decimal number in a localized compact form.
51+
* Compact number formatting is designed for an environment with limited space.
52+
* For example, displaying the formatted number {@code 7M} instead of {@code
53+
* 7,000,000.00} in the {@link java.util.Locale#US US locale}. The {@code
54+
* CompactNumberFormat} class is defined by LDML's specification for
5555
* <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats">
56-
* Compact Number Formats</a>. A compact number formatting refers
57-
* to the representation of a number in a shorter form, based on the patterns
58-
* provided for a given locale.
56+
* Compact Number Formats</a>.
5957
*
60-
* <p>
61-
* For example:
62-
* <br>In the {@link java.util.Locale#US US locale}, {@code 1000} can be formatted
63-
* as {@code "1K"}, and {@code 1000000} as {@code "1M"}, depending upon the
64-
* {@linkplain ##compact_number_style style} used.
65-
* <br>In the {@code "hi_IN"} locale, {@code 1000} can be formatted as
66-
* "1 \u0939\u091C\u093C\u093E\u0930", and {@code 50000000} as "5 \u0915.",
67-
* depending upon the {@linkplain ##compact_number_style style} used.
58+
* <h2>Getting a CompactNumberFormat</h2>
59+
* To get a compact number format, use one of the ways listed below.
60+
* <ul>
61+
* <li> Use the factory method {@link NumberFormat#getCompactNumberInstance()}
62+
* to obtain a format for the default locale with
63+
* {@link NumberFormat.Style#SHORT SHORT} style.
64+
* <li> Use the factory methood {@link NumberFormat#getCompactNumberInstance(Locale, Style)}
65+
* to obtain a format for a different locale
66+
* and to control the {@linkplain ##compact_number_style Style}.
67+
* <li> Use one of the {@code CompactNumberFormat} constructors, for example, {@link
68+
* CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
69+
* CompactNumberFormat(decimalPattern, symbols, compactPatterns)}, to obtain a
70+
* {@code CompactNumberFormat} with further customization.
71+
* </ul>
72+
* <p>If a standard compact format for a given locale and {@link
73+
* ##compact_number_style style} is desired, it is recommended to use one of the
74+
* NumberFormat factory methods listed above. To use an instance method
75+
* defined by {@code CompactNumberFormat}, the {@code NumberFormat} returned by
76+
* these factory methods should be type checked before converted to {@code CompactNumberFormat}.
77+
* If the installed locale-sensitive service implementation does not support
78+
* the given {@code Locale}, the parent locale chain will be looked up, and
79+
* a {@code Locale} used that is supported.
6880
*
69-
* <p>
70-
* To obtain a {@code CompactNumberFormat} for a locale, use one
71-
* of the factory methods given by {@code NumberFormat} for compact number
72-
* formatting. For example,
73-
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
81+
* <h2><a id="compact_number_style">Style</a></h2>
82+
* When using {@link NumberFormat#getCompactNumberInstance(Locale, Style)}, a
83+
* compact form can be retrieved with either a {@link NumberFormat.Style#SHORT
84+
* SHORT} or {@link NumberFormat.Style#LONG LONG} style.
85+
* For example, a {@link NumberFormat.Style#SHORT SHORT} style compact number instance in
86+
* the {@link java.util.Locale#US US locale} formats {@code 10000} as {@code
87+
* "10K"}. However, a {@link NumberFormat.Style#LONG LONG} style instance in
88+
* the same locale formats {@code 10000} as {@code "10 thousand"}.
7489
*
75-
* <blockquote>{@snippet lang=java :
76-
* NumberFormat fmt = NumberFormat.getCompactNumberInstance(
77-
* Locale.forLanguageTag("hi-IN"), NumberFormat.Style.SHORT);
78-
* String result = fmt.format(1000);
79-
* }</blockquote>
90+
* <h2>Using CompactNumberFormat</h2>
91+
* The following is an example of formatting and parsing in a localized manner,
8092
*
81-
* <h2><a id="compact_number_style">Style</a></h2>
82-
* <p>
83-
* A number can be formatted in the compact forms with two different
84-
* styles, {@link NumberFormat.Style#SHORT SHORT}
85-
* and {@link NumberFormat.Style#LONG LONG}. Use
86-
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)} for formatting and
87-
* parsing a number in {@link NumberFormat.Style#SHORT SHORT} or
88-
* {@link NumberFormat.Style#LONG LONG} compact form,
89-
* where the given {@code Style} parameter requests the desired
90-
* format. A {@link NumberFormat.Style#SHORT SHORT} style
91-
* compact number instance in the {@link java.util.Locale#US US locale} formats
92-
* {@code 10000} as {@code "10K"}. However, a
93-
* {@link NumberFormat.Style#LONG LONG} style instance in same locale
94-
* formats {@code 10000} as {@code "10 thousand"}.
93+
* {@snippet lang=java :
94+
* NumberFormat compactFormat = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
95+
* compactFormat.format(1000); // returns "1K"
96+
* compactFormat.parse("1K"); // returns 1000
97+
* }
98+
*
99+
* <h2 id="formatting">Formatting</h2>
100+
* The default formatting behavior returns a formatted string with no fractional
101+
* digits, however users can use the {@link #setMinimumFractionDigits(int)}
102+
* method to include the fractional part.
103+
* The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
104+
* not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
105+
* reason, the patterns provided for formatting contain only the minimum
106+
* integer digits, prefix and/or suffix, but no fractional part.
107+
* For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
108+
* selected for formatting a number is {@code "0"} (special pattern),
109+
* either explicit or defaulted, then the general number formatting provided by
110+
* {@link java.text.DecimalFormat DecimalFormat}
111+
* for the specified locale is used.
112+
*
113+
* <h3>Rounding</h3>
114+
* {@code CompactNumberFormat} provides rounding modes defined in
115+
* {@link java.math.RoundingMode} for formatting. By default, it uses
116+
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
117+
*
118+
* <h2>Parsing</h2>
119+
* The default parsing behavior does not allow a grouping separator until
120+
* grouping used is set to {@code true} by using
121+
* {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
122+
* depends on the {@link #isParseIntegerOnly()}. For example, if the
123+
* parse integer only is set to true, then the fractional part is skipped.
95124
*
96125
* <h2><a id="compact_number_patterns">Compact Number Patterns</a></h2>
97126
* <p>
98-
* The compact number patterns are represented in a series of patterns where each
99-
* pattern is used to format a range of numbers. An example of
100-
* {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
127+
* The {@code compactPatterns} in {@link
128+
* CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
129+
* CompactNumberFormat(decimalPattern, symbols, compactPatterns)} are represented
130+
* as a series of strings, where each string is a {@link ##compact_number_syntax
131+
* pattern} that is used to format a range of numbers.
132+
*
133+
* <p> An example of the {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
101134
* for the {@link java.util.Locale#US US locale} is {@code {"", "", "", "0K",
102135
* "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"}},
103136
* ranging from {@code 10}<sup>{@code 0}</sup> to {@code 10}<sup>{@code 14}</sup>.
104137
* There can be any number of patterns and they are
105138
* strictly index based starting from the range {@code 10}<sup>{@code 0}</sup>.
106-
* For example, in the above patterns, pattern at index 3
107-
* ({@code "0K"}) is used for formatting {@code number >= 1000 and number < 10000},
108-
* pattern at index 4 ({@code "00K"}) is used for formatting
109-
* {@code number >= 10000 and number < 100000} and so on. In most of the locales,
110-
* patterns with the range
139+
* For example, in the above patterns, the pattern at index 3
140+
* ({@code "0K"}) is used for formatting a number in the range: {@code 1000 <= number < 10000},
141+
* index 4 ({@code "00K"}) for formatting a number the range: {@code 10000 <=
142+
* number < 100000}, and so forth.
143+
* <p>In most locales, patterns with the range
111144
* {@code 10}<sup>{@code 0}</sup>-{@code 10}<sup>{@code 2}</sup> are empty
112145
* strings, which implicitly means a special pattern {@code "0"}.
113146
* A special pattern {@code "0"} is used for any range which does not contain
114147
* a compact pattern. This special pattern can appear explicitly for any specific
115148
* range, or considered as a default pattern for an empty string.
116149
*
117-
* <p>
150+
* <h3>Negative Subpatterns</h3>
118151
* A compact pattern contains a positive and negative subpattern
119-
* separated by a subpattern boundary character {@code ';' (U+003B)},
152+
* separated by a subpattern boundary character {@code ';'},
120153
* for example, {@code "0K;-0K"}. Each subpattern has a prefix,
121154
* minimum integer digits, and suffix. The negative subpattern
122155
* is optional, if absent, then the positive subpattern prefixed with the
123-
* minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the negative
156+
* minus sign {@code '-' (U+002D HYPHEN-MINUS)} is used as the negative
124157
* subpattern. That is, {@code "0K"} alone is equivalent to {@code "0K;-0K"}.
125158
* If there is an explicit negative subpattern, it serves only to specify
126159
* the negative prefix and suffix. The number of minimum integer digits,
127160
* and other characteristics are all the same as the positive pattern.
128161
* That means that {@code "0K;-00K"} produces precisely the same behavior
129162
* as {@code "0K;-0K"}.
130163
*
131-
* <p>
164+
* <h4>Escaping Special Characters</h4>
132165
* Many characters in a compact pattern are taken literally, they are matched
133166
* during parsing and output unchanged during formatting.
134167
* {@linkplain DecimalFormat##special_pattern_character Special characters},
135168
* on the other hand, stand for other characters, strings, or classes of
136-
* characters. They must be quoted, using single quote {@code ' (U+0027)}
169+
* characters. These characters must be quoted using single quotes {@code ' (U+0027)}
137170
* unless noted otherwise, if they are to appear in the prefix or suffix
138171
* as literals. For example, 0\u0915'.'.
139172
*
140173
* <h3>Plurals</h3>
174+
* <p> {@code CompactNumberFormat} support patterns for both singular and plural
175+
* compact forms. For the plural form, the {@code Pattern} should consist
176+
* of {@code PluralPattern}(s) separated by a space ' ' (U+0020) that are enumerated
177+
* within a pair of curly brackets '{' (U+007B) and '}' (U+007D).
178+
* In this format, each {@code PluralPattern} consists of its {@code count},
179+
* followed by a single colon {@code ':' (U+003A)} and a {@code SimplePattern}.
180+
* As a space is reserved for separating subsequent {@code PluralPattern}s, it must
181+
* be quoted to be used literally in either the {@code prefix} or {@code suffix}.
141182
* <p>
142-
* In case some localization requires compact number patterns to be different for
143-
* plurals, each singular and plural pattern can be enumerated within a pair of
144-
* curly brackets <code>'{' (U+007B)</code> and <code>'}' (U+007D)</code>, separated
145-
* by a space {@code ' ' (U+0020)}. If this format is used, each pattern needs to be
146-
* prepended by its {@code count}, followed by a single colon {@code ':' (U+003A)}.
147-
* If the pattern includes spaces literally, they must be quoted.
183+
* For example, while the pattern representing millions ({@code 10}<sup>{@code 6}
184+
* </sup>) in the US locale can be specified as the SimplePattern: {@code "0 Million"}, for the
185+
* German locale it can be specified as the PluralPattern:
186+
* {@code "{one:0' 'Million other:0' 'Millionen}"}.
187+
*
148188
* <p>
149-
* For example, the compact number pattern representing millions in German locale can be
150-
* specified as {@code "{one:0' 'Million other:0' 'Millionen}"}. The {@code count}
151-
* follows LDML's
189+
* <a id="compact_number_syntax">A compact pattern has the following syntax, with {@code count}</a>
190+
* following LDML's
152191
* <a href="https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules">
153-
* Language Plural Rules</a>.
154-
* <p>
155-
* A compact pattern has the following syntax:
192+
* Language Plural Rules</a>:
156193
* <blockquote><pre>
157194
* <i>Pattern:</i>
158195
* <i>SimplePattern</i>
@@ -179,37 +216,12 @@
179216
* 0 <i>MinimumInteger</i>
180217
* </pre></blockquote>
181218
*
182-
* <h2>Formatting</h2>
183-
* The default formatting behavior returns a formatted string with no fractional
184-
* digits, however users can use the {@link #setMinimumFractionDigits(int)}
185-
* method to include the fractional part.
186-
* The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
187-
* not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
188-
* reason, the patterns provided for formatting contain only the minimum
189-
* integer digits, prefix and/or suffix, but no fractional part.
190-
* For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
191-
* selected for formatting a number is {@code "0"} (special pattern),
192-
* either explicit or defaulted, then the general number formatting provided by
193-
* {@link java.text.DecimalFormat DecimalFormat}
194-
* for the specified locale is used.
195-
*
196-
* <h2>Parsing</h2>
197-
* The default parsing behavior does not allow a grouping separator until
198-
* grouping used is set to {@code true} by using
199-
* {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
200-
* depends on the {@link #isParseIntegerOnly()}. For example, if the
201-
* parse integer only is set to true, then the fractional part is skipped.
202-
*
203-
* <h2>Rounding</h2>
204-
* {@code CompactNumberFormat} provides rounding modes defined in
205-
* {@link java.math.RoundingMode} for formatting. By default, it uses
206-
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
207-
*
208219
* @spec https://www.unicode.org/reports/tr35
209220
* Unicode Locale Data Markup Language (LDML)
210221
* @see NumberFormat.Style
211222
* @see NumberFormat
212223
* @see DecimalFormat
224+
* @see Locale
213225
* @since 12
214226
*/
215227
public final class CompactNumberFormat extends NumberFormat {
@@ -389,10 +401,19 @@ public final class CompactNumberFormat extends NumberFormat {
389401
* To obtain the instance of {@code CompactNumberFormat} with the standard
390402
* compact patterns for a {@code Locale} and {@code Style},
391403
* it is recommended to use the factory methods given by
392-
* {@code NumberFormat} for compact number formatting. For example,
393-
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
404+
* {@code NumberFormat} for compact number formatting.
405+
*
406+
* <p>Below is an example of using the constructor,
407+
*
408+
* {@snippet lang=java :
409+
* String[] compactPatterns = {"", "", "", "a lot"};
410+
* NumberFormat fmt = new CompactNumberFormat("00", DecimalFormatSymbols.getInstance(Locale.US), compactPatterns);
411+
* fmt.format(1); // returns "01"
412+
* fmt.format(1000); // returns "a lot"
413+
* }
394414
*
395-
* @param decimalPattern a decimal pattern for general number formatting
415+
* @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
416+
* for general number formatting
396417
* @param symbols the set of symbols to be used
397418
* @param compactPatterns an array of
398419
* {@linkplain ##compact_number_patterns compact number patterns}
@@ -419,7 +440,8 @@ public CompactNumberFormat(String decimalPattern,
419440
* {@code NumberFormat} for compact number formatting. For example,
420441
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
421442
*
422-
* @param decimalPattern a decimal pattern for general number formatting
443+
* @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
444+
* for general number formatting
423445
* @param symbols the set of symbols to be used
424446
* @param compactPatterns an array of
425447
* {@linkplain ##compact_number_patterns compact number patterns}

0 commit comments

Comments
 (0)