2 *******************************************************************************
\r
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.text;
\r
10 import java.io.IOException;
\r
11 import java.io.InvalidObjectException;
\r
12 import java.io.ObjectInputStream;
\r
13 import java.io.ObjectOutputStream;
\r
14 import java.math.BigInteger;
\r
15 import java.text.FieldPosition;
\r
16 import java.text.Format;
\r
17 import java.text.ParseException;
\r
18 import java.text.ParsePosition;
\r
19 import java.util.Collections;
\r
20 import java.util.Locale;
\r
21 import java.util.MissingResourceException;
\r
22 import java.util.Set;
\r
24 import com.ibm.icu.impl.ICUResourceBundle;
\r
25 import com.ibm.icu.util.Currency;
\r
26 import com.ibm.icu.util.CurrencyAmount;
\r
27 import com.ibm.icu.util.ULocale;
\r
28 import com.ibm.icu.util.UResourceBundle;
\r
31 * {@icuenhanced java.text.NumberFormat}.{@icu _usage_}
\r
33 * <code>NumberFormat</code> is the abstract base class for all number
\r
34 * formats. This class provides the interface for formatting and parsing
\r
35 * numbers. <code>NumberFormat</code> also provides methods for determining
\r
36 * which locales have number formats, and what their names are.
\r
38 * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
\r
39 * Your code can be completely independent of the locale conventions for
\r
40 * decimal points, thousands-separators, or even the particular decimal
\r
41 * digits used, or whether the number format is even decimal.
\r
44 * To format a number for the current Locale, use one of the factory
\r
48 * myString = NumberFormat.getInstance().format(myNumber);
\r
51 * If you are formatting multiple numbers, it is
\r
52 * more efficient to get the format and use it multiple times so that
\r
53 * the system doesn't have to fetch the information about the local
\r
54 * language and country conventions multiple times.
\r
57 * NumberFormat nf = NumberFormat.getInstance();
\r
58 * for (int i = 0; i < a.length; ++i) {
\r
59 * output.println(nf.format(myNumber[i]) + "; ");
\r
63 * To format a number for a different Locale, specify it in the
\r
64 * call to <code>getInstance</code>.
\r
67 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
\r
70 * You can also use a <code>NumberFormat</code> to parse numbers:
\r
73 * myNumber = nf.parse(myString);
\r
76 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
\r
77 * normal number format. Use <code>getIntegerInstance</code> to get an
\r
78 * integer number format. Use <code>getCurrencyInstance</code> to get the
\r
79 * currency number format. And use <code>getPercentInstance</code> to get a
\r
80 * format for displaying percentages. With this format, a fraction like
\r
81 * 0.53 is displayed as 53%.
\r
84 * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
\r
85 * as parameter to get the correct instance.
\r
87 * use getInstance(...NUMBERSTYLE) to get the normal number format,
\r
88 * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
\r
89 * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
\r
90 * getInstance(...INTEGERSTYLE) to get an integer number format,
\r
91 * getInstance(...CURRENCYSTYLE) to get the currency number format,
\r
92 * in which the currency is represented by its symbol, for example, "$3.00".
\r
93 * getInstance(...ISOCURRENCYSTYLE) to get the currency number format,
\r
94 * in which the currency is represented by its ISO code, for example "USD3.00".
\r
95 * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
\r
96 * in which the currency is represented by its full name in plural format,
\r
97 * for example, "3.00 US dollars" or "1.00 US dollar".
\r
101 * You can also control the display of numbers with such methods as
\r
102 * <code>setMinimumFractionDigits</code>.
\r
103 * If you want even more control over the format or parsing,
\r
104 * or want to give your users more control,
\r
105 * you can try casting the <code>NumberFormat</code> you get from the factory methods
\r
106 * to a <code>DecimalFormat</code>. This will work for the vast majority
\r
107 * of locales; just remember to put it in a <code>try</code> block in case you
\r
108 * encounter an unusual one.
\r
111 * NumberFormat is designed such that some controls
\r
112 * work for formatting and others work for parsing. The following is
\r
113 * the detailed description for each these control methods,
\r
115 * setParseIntegerOnly : only affects parsing, e.g.
\r
116 * if true, "3456.78" -> 3456 (and leaves the parse position just after '6')
\r
117 * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')
\r
118 * This is independent of formatting. If you want to not show a decimal point
\r
119 * where there might be no digits after the decimal point, use
\r
120 * setDecimalSeparatorAlwaysShown on DecimalFormat.
\r
122 * You can also use forms of the <code>parse</code> and <code>format</code>
\r
123 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
\r
126 * <li> progressively parse through pieces of a string
\r
127 * <li> align the decimal point and other areas
\r
129 * For example, you can align numbers in two ways:
\r
131 * <li> If you are using a monospaced font with spacing for alignment,
\r
132 * you can pass the <code>FieldPosition</code> in your format call, with
\r
133 * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
\r
134 * <code>getEndIndex</code> will be set to the offset between the
\r
135 * last character of the integer and the decimal. Add
\r
136 * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
\r
138 * <li> If you are using proportional fonts,
\r
139 * instead of padding with spaces, measure the width
\r
140 * of the string in pixels from the start to <code>getEndIndex</code>.
\r
141 * Then move the pen by
\r
142 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
\r
143 * It also works where there is no decimal, but possibly additional
\r
144 * characters at the end, e.g., with parentheses in negative
\r
145 * numbers: "(12)" for -12.
\r
148 * <h4>Synchronization</h4>
\r
150 * Number formats are generally not synchronized. It is recommended to create
\r
151 * separate format instances for each thread. If multiple threads access a format
\r
152 * concurrently, it must be synchronized externally.
\r
155 * <h4>DecimalFormat</h4>
\r
156 * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
\r
157 * NumberFormat API is essentially an abstraction from DecimalFormat's API.
\r
158 * Refer to DecimalFormat for more information about this API.</p>
\r
160 * see DecimalFormat
\r
161 * see java.text.ChoiceFormat
\r
162 * @author Mark Davis
\r
163 * @author Helena Shih
\r
167 public abstract class NumberFormat extends UFormat {
\r
170 * {@icu} Constant to specify normal number style of format.
\r
173 public static final int NUMBERSTYLE = 0;
\r
175 * {@icu} Constant to specify currency style of format which uses currency symbol
\r
176 * to represent currency, for example: "$3.00".
\r
179 public static final int CURRENCYSTYLE = 1;
\r
181 * {@icu} Constant to specify a style of format to display percent.
\r
184 public static final int PERCENTSTYLE = 2;
\r
186 * {@icu} Constant to specify a style of format to display scientific number.
\r
189 public static final int SCIENTIFICSTYLE = 3;
\r
191 * {@icu} Constant to specify a integer number style format.
\r
194 public static final int INTEGERSTYLE = 4;
\r
196 * {@icu} Constant to specify currency style of format which uses currency
\r
197 * ISO code to represent currency, for example: "USD3.00".
\r
200 public static final int ISOCURRENCYSTYLE = 5;
\r
202 * {@icu} Constant to specify currency style of format which uses currency
\r
203 * long name with plural format to represent currency, for example,
\r
204 * "3.00 US Dollars".
\r
207 public static final int PLURALCURRENCYSTYLE = 6;
\r
210 * Field constant used to construct a FieldPosition object. Signifies that
\r
211 * the position of the integer part of a formatted number should be returned.
\r
212 * @see java.text.FieldPosition
\r
215 public static final int INTEGER_FIELD = 0;
\r
218 * Field constant used to construct a FieldPosition object. Signifies that
\r
219 * the position of the fraction part of a formatted number should be returned.
\r
220 * @see java.text.FieldPosition
\r
223 public static final int FRACTION_FIELD = 1;
\r
226 * Formats a number and appends the resulting text to the given string buffer.
\r
227 * {@icunote} recognizes <code>BigInteger</code>
\r
228 * and <code>BigDecimal</code> objects.
\r
229 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
232 public StringBuffer format(Object number,
\r
233 StringBuffer toAppendTo,
\r
234 FieldPosition pos) {
\r
235 if (number instanceof Long) {
\r
236 return format(((Long)number).longValue(), toAppendTo, pos);
\r
237 } else if (number instanceof BigInteger) {
\r
238 return format((BigInteger) number, toAppendTo, pos);
\r
239 } else if (number instanceof java.math.BigDecimal) {
\r
240 return format((java.math.BigDecimal) number, toAppendTo, pos);
\r
241 } else if (number instanceof com.ibm.icu.math.BigDecimal) {
\r
242 return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);
\r
243 } else if (number instanceof CurrencyAmount) {
\r
244 return format((CurrencyAmount)number, toAppendTo, pos);
\r
245 } else if (number instanceof Number) {
\r
246 return format(((Number)number).doubleValue(), toAppendTo, pos);
\r
248 throw new IllegalArgumentException("Cannot format given Object as a Number");
\r
253 * Parses text from a string to produce a number.
\r
254 * @param source the String to parse
\r
255 * @param parsePosition the position at which to start the parse
\r
256 * @return the parsed number, or null
\r
257 * @see java.text.NumberFormat#parseObject(String, ParsePosition)
\r
260 public final Object parseObject(String source,
\r
261 ParsePosition parsePosition) {
\r
262 return parse(source, parsePosition);
\r
266 * Specialization of format.
\r
267 * @see java.text.Format#format(Object)
\r
270 public final String format(double number) {
\r
271 return format(number,new StringBuffer(),
\r
272 new FieldPosition(0)).toString();
\r
276 * Specialization of format.
\r
277 * @see java.text.Format#format(Object)
\r
280 public final String format(long number) {
\r
281 StringBuffer buf = new StringBuffer(19);
\r
282 FieldPosition pos = new FieldPosition(0);
\r
283 format(number, buf, pos);
\r
284 return buf.toString();
\r
288 * {@icu} Convenience method to format a BigInteger.
\r
291 public final String format(BigInteger number) {
\r
292 return format(number, new StringBuffer(),
\r
293 new FieldPosition(0)).toString();
\r
297 * Convenience method to format a BigDecimal.
\r
300 public final String format(java.math.BigDecimal number) {
\r
301 return format(number, new StringBuffer(),
\r
302 new FieldPosition(0)).toString();
\r
306 * {@icu} Convenience method to format an ICU BigDecimal.
\r
309 public final String format(com.ibm.icu.math.BigDecimal number) {
\r
310 return format(number, new StringBuffer(),
\r
311 new FieldPosition(0)).toString();
\r
315 * {@icu} Convenience method to format a CurrencyAmount.
\r
318 public final String format(CurrencyAmount currAmt) {
\r
319 return format(currAmt, new StringBuffer(),
\r
320 new FieldPosition(0)).toString();
\r
324 * Specialization of format.
\r
325 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
328 public abstract StringBuffer format(double number,
\r
329 StringBuffer toAppendTo,
\r
330 FieldPosition pos);
\r
333 * Specialization of format.
\r
334 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
337 public abstract StringBuffer format(long number,
\r
338 StringBuffer toAppendTo,
\r
339 FieldPosition pos);
\r
341 * {@icu} Formats a BigInteger. Specialization of format.
\r
342 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
345 public abstract StringBuffer format(BigInteger number,
\r
346 StringBuffer toAppendTo,
\r
347 FieldPosition pos);
\r
349 * {@icu} Formats a BigDecimal. Specialization of format.
\r
350 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
353 public abstract StringBuffer format(java.math.BigDecimal number,
\r
354 StringBuffer toAppendTo,
\r
355 FieldPosition pos);
\r
357 * {@icu} Formats an ICU BigDecimal. Specialization of format.
\r
358 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
361 public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,
\r
362 StringBuffer toAppendTo,
\r
363 FieldPosition pos);
\r
365 * {@icu} Formats a CurrencyAmount. Specialization of format.
\r
366 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
\r
369 public StringBuffer format(CurrencyAmount currAmt,
\r
370 StringBuffer toAppendTo,
\r
371 FieldPosition pos) {
\r
372 // Default implementation -- subclasses may override
\r
373 Currency save = getCurrency(), curr = currAmt.getCurrency();
\r
374 boolean same = curr.equals(save);
\r
375 if (!same) setCurrency(curr);
\r
376 format(currAmt.getNumber(), toAppendTo, pos);
\r
377 if (!same) setCurrency(save);
\r
382 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
\r
383 * Long.MAX_VALUE] and with no decimals), otherwise a Double.
\r
384 * If IntegerOnly is set, will stop at a decimal
\r
385 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
\r
387 * Does not throw an exception; if no object can be parsed, index is
\r
389 * @see #isParseIntegerOnly
\r
390 * @see java.text.Format#parseObject(String, ParsePosition)
\r
393 public abstract Number parse(String text, ParsePosition parsePosition);
\r
396 * Parses text from the beginning of the given string to produce a number.
\r
397 * The method might not use the entire text of the given string.
\r
399 * @param text A String whose beginning should be parsed.
\r
400 * @return A Number parsed from the string.
\r
401 * @throws ParseException if the beginning of the specified string
\r
402 * cannot be parsed.
\r
406 //Bug 4375399 [Richard/GCL]
\r
407 public Number parse(String text) throws ParseException {
\r
408 ParsePosition parsePosition = new ParsePosition(0);
\r
409 Number result = parse(text, parsePosition);
\r
410 if (parsePosition.getIndex() == 0) {
\r
411 throw new ParseException("Unparseable number: \"" + text + '"',
\r
412 parsePosition.getErrorIndex());
\r
418 * Parses text from the given string as a CurrencyAmount. Unlike
\r
419 * the parse() method, this method will attempt to parse a generic
\r
420 * currency name, searching for a match of this object's locale's
\r
421 * currency display names, or for a 3-letter ISO currency code.
\r
422 * This method will fail if this format is not a currency format,
\r
423 * that is, if it does not contain the currency pattern symbol
\r
424 * (U+00A4) in its prefix or suffix.
\r
426 * @param text the string to parse
\r
427 * @param pos input-output position; on input, the position within
\r
428 * text to match; must have 0 <= pos.getIndex() < text.length();
\r
429 * on output, the position after the last matched character. If
\r
430 * the parse fails, the position in unchanged upon output.
\r
431 * @return a CurrencyAmount, or null upon failure
\r
433 CurrencyAmount parseCurrency(String text, ParsePosition pos) {
\r
435 // Default implementation only -- subclasses should override
\r
436 Number n = parse(text, pos);
\r
437 return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
\r
442 * Returns true if this format will parse numbers as integers only.
\r
443 * For example in the English locale, with ParseIntegerOnly true, the
\r
444 * string "1234." would be parsed as the integer value 1234 and parsing
\r
445 * would stop at the "." character. The decimal separator accepted
\r
446 * by the parse operation is locale-dependent and determined by the
\r
448 * @return true if this will parse integers only
\r
451 public boolean isParseIntegerOnly() {
\r
452 return parseIntegerOnly;
\r
456 * Sets whether or not numbers should be parsed as integers only.
\r
457 * @param value true if this should parse integers only
\r
458 * @see #isParseIntegerOnly
\r
461 public void setParseIntegerOnly(boolean value) {
\r
462 parseIntegerOnly = value;
\r
466 * {@icu} Sets whether strict parsing is in effect. When this is true, the
\r
467 * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
\r
468 * <li>Leading zeros<br>
\r
469 * '00', '0123' fail the parse, but '0' and '0.001' pass</li>
\r
470 * <li>Leading or doubled grouping separators<br>
\r
471 * ',123' and '1,,234" fail</li>
\r
472 * <li>Groups of incorrect length when grouping is used<br>
\r
473 * '1,23' and '1234,567' fail, but '1234' passes</li>
\r
474 * <li>Grouping separators used in numbers followed by exponents<br>
\r
475 * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
\r
476 * not followed by a number)</li>
\r
478 * When strict parsing is off, leading zeros and all grouping separators are ignored.
\r
479 * This is the default behavior.
\r
480 * @param value True to enable strict parsing. Default is false.
\r
481 * @see #isParseStrict
\r
484 public void setParseStrict(boolean value) {
\r
485 parseStrict = value;
\r
489 * {@icu} Returns whether strict parsing is in effect.
\r
490 * @return true if strict parsing is in effect
\r
491 * @see #setParseStrict
\r
494 public boolean isParseStrict() {
\r
495 return parseStrict;
\r
498 //============== Locale Stuff =====================
\r
501 * Returns the default number format for the current default locale.
\r
502 * The default format is one of the styles provided by the other
\r
503 * factory methods: getNumberInstance, getIntegerInstance,
\r
504 * getCurrencyInstance or getPercentInstance.
\r
505 * Exactly which one is locale-dependent.
\r
508 //Bug 4408066 [Richard/GCL]
\r
509 public final static NumberFormat getInstance() {
\r
510 return getInstance(ULocale.getDefault(), NUMBERSTYLE);
\r
514 * Returns the default number format for the specified locale.
\r
515 * The default format is one of the styles provided by the other
\r
516 * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
\r
517 * Exactly which one is locale-dependent.
\r
520 public static NumberFormat getInstance(Locale inLocale) {
\r
521 return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
\r
525 * {@icu} Returns the default number format for the specified locale.
\r
526 * The default format is one of the styles provided by the other
\r
527 * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
\r
528 * Exactly which one is locale-dependent.
\r
531 public static NumberFormat getInstance(ULocale inLocale) {
\r
532 return getInstance(inLocale, NUMBERSTYLE);
\r
536 * {@icu} Returns a specific style number format for default locale.
\r
537 * @param style number format style
\r
540 public final static NumberFormat getInstance(int style) {
\r
541 return getInstance(ULocale.getDefault(), style);
\r
545 * {@icu} Returns a specific style number format for a specific locale.
\r
546 * @param inLocale the specific locale.
\r
547 * @param style number format style
\r
550 public static NumberFormat getInstance(Locale inLocale, int style) {
\r
551 return getInstance(ULocale.forLocale(inLocale), style);
\r
556 * Returns a general-purpose number format for the current default locale.
\r
559 public final static NumberFormat getNumberInstance() {
\r
560 return getInstance(ULocale.getDefault(), NUMBERSTYLE);
\r
564 * Returns a general-purpose number format for the specified locale.
\r
567 public static NumberFormat getNumberInstance(Locale inLocale) {
\r
568 return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
\r
572 * {@icu} Returns a general-purpose number format for the specified locale.
\r
575 public static NumberFormat getNumberInstance(ULocale inLocale) {
\r
576 return getInstance(inLocale, NUMBERSTYLE);
\r
580 * Returns an integer number format for the current default locale. The
\r
581 * returned number format is configured to round floating point numbers
\r
582 * to the nearest integer using IEEE half-even rounding (see {@link
\r
583 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
\r
584 * and to parse only the integer part of an input string (see {@link
\r
585 * #isParseIntegerOnly isParseIntegerOnly}).
\r
587 * @return a number format for integer values
\r
590 //Bug 4408066 [Richard/GCL]
\r
591 public final static NumberFormat getIntegerInstance() {
\r
592 return getInstance(ULocale.getDefault(), INTEGERSTYLE);
\r
596 * Returns an integer number format for the specified locale. The
\r
597 * returned number format is configured to round floating point numbers
\r
598 * to the nearest integer using IEEE half-even rounding (see {@link
\r
599 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
\r
600 * and to parse only the integer part of an input string (see {@link
\r
601 * #isParseIntegerOnly isParseIntegerOnly}).
\r
603 * @param inLocale the locale for which a number format is needed
\r
604 * @return a number format for integer values
\r
607 //Bug 4408066 [Richard/GCL]
\r
608 public static NumberFormat getIntegerInstance(Locale inLocale) {
\r
609 return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
\r
613 * {@icu} Returns an integer number format for the specified locale. The
\r
614 * returned number format is configured to round floating point numbers
\r
615 * to the nearest integer using IEEE half-even rounding (see {@link
\r
616 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
\r
617 * and to parse only the integer part of an input string (see {@link
\r
618 * #isParseIntegerOnly isParseIntegerOnly}).
\r
620 * @param inLocale the locale for which a number format is needed
\r
621 * @return a number format for integer values
\r
624 public static NumberFormat getIntegerInstance(ULocale inLocale) {
\r
625 return getInstance(inLocale, INTEGERSTYLE);
\r
629 * Returns a currency format for the current default locale.
\r
630 * @return a number format for currency
\r
633 public final static NumberFormat getCurrencyInstance() {
\r
634 return getInstance(ULocale.getDefault(), CURRENCYSTYLE);
\r
638 * Returns a currency format for the specified locale.
\r
639 * @return a number format for currency
\r
642 public static NumberFormat getCurrencyInstance(Locale inLocale) {
\r
643 return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
\r
647 * {@icu} Returns a currency format for the specified locale.
\r
648 * @return a number format for currency
\r
651 public static NumberFormat getCurrencyInstance(ULocale inLocale) {
\r
652 return getInstance(inLocale, CURRENCYSTYLE);
\r
656 * Returns a percentage format for the current default locale.
\r
657 * @return a number format for percents
\r
660 public final static NumberFormat getPercentInstance() {
\r
661 return getInstance(ULocale.getDefault(), PERCENTSTYLE);
\r
665 * Returns a percentage format for the specified locale.
\r
666 * @return a number format for percents
\r
669 public static NumberFormat getPercentInstance(Locale inLocale) {
\r
670 return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
\r
674 * {@icu} Returns a percentage format for the specified locale.
\r
675 * @return a number format for percents
\r
678 public static NumberFormat getPercentInstance(ULocale inLocale) {
\r
679 return getInstance(inLocale, PERCENTSTYLE);
\r
683 * {@icu} Returns a scientific format for the current default locale.
\r
684 * @return a scientific number format
\r
687 public final static NumberFormat getScientificInstance() {
\r
688 return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE);
\r
692 * {@icu} Returns a scientific format for the specified locale.
\r
693 * @return a scientific number format
\r
696 public static NumberFormat getScientificInstance(Locale inLocale) {
\r
697 return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
\r
701 * {@icu} Returns a scientific format for the specified locale.
\r
702 * @return a scientific number format
\r
705 public static NumberFormat getScientificInstance(ULocale inLocale) {
\r
706 return getInstance(inLocale, SCIENTIFICSTYLE);
\r
709 // ===== Factory stuff =====
\r
711 * A NumberFormatFactory is used to register new number formats. The factory
\r
712 * should be able to create any of the predefined formats for each locale it
\r
713 * supports. When registered, the locales it supports extend or override the
\r
714 * locales already supported by ICU.
\r
716 * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
\r
717 * ULocale instead of Locale. Instead of overriding createFormat(Locale, int),
\r
718 * new implementations should override createFactory(ULocale, int). Note that
\r
719 * one of these two methods <b>MUST</b> be overridden or else an infinite
\r
724 public static abstract class NumberFormatFactory {
\r
726 * Value passed to format requesting a default number format.
\r
729 public static final int FORMAT_NUMBER = NUMBERSTYLE;
\r
732 * Value passed to format requesting a currency format.
\r
735 public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
\r
738 * Value passed to format requesting a percent format.
\r
741 public static final int FORMAT_PERCENT = PERCENTSTYLE;
\r
744 * Value passed to format requesting a scientific format.
\r
747 public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
\r
750 * Value passed to format requesting an integer format.
\r
753 public static final int FORMAT_INTEGER = INTEGERSTYLE;
\r
756 * Returns true if this factory is visible. Default is true.
\r
757 * If not visible, the locales supported by this factory will not
\r
758 * be listed by getAvailableLocales. This value must not change.
\r
759 * @return true if the factory is visible.
\r
762 public boolean visible() {
\r
767 * Returns an immutable collection of the locale names directly
\r
768 * supported by this factory.
\r
769 * @return the supported locale names.
\r
772 public abstract Set<String> getSupportedLocaleNames();
\r
775 * Returns a number format of the appropriate type. If the locale
\r
776 * is not supported, return null. If the locale is supported, but
\r
777 * the type is not provided by this service, return null. Otherwise
\r
778 * return an appropriate instance of NumberFormat.
\r
779 * <b>Note:</b> as of ICU4J 3.2, implementations should override
\r
780 * this method instead of createFormat(Locale, int).
\r
781 * @param loc the locale for which to create the format
\r
782 * @param formatType the type of format
\r
783 * @return the NumberFormat, or null.
\r
786 public NumberFormat createFormat(ULocale loc, int formatType) {
\r
787 return createFormat(loc.toLocale(), formatType);
\r
791 * Returns a number format of the appropriate type. If the locale
\r
792 * is not supported, return null. If the locale is supported, but
\r
793 * the type is not provided by this service, return null. Otherwise
\r
794 * return an appropriate instance of NumberFormat.
\r
795 * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
\r
796 * overridden instead of this method. This method is no longer
\r
797 * abstract and delegates to that method.
\r
798 * @param loc the locale for which to create the format
\r
799 * @param formatType the type of format
\r
800 * @return the NumberFormat, or null.
\r
803 public NumberFormat createFormat(Locale loc, int formatType) {
\r
804 return createFormat(ULocale.forLocale(loc), formatType);
\r
810 protected NumberFormatFactory() {
\r
815 * A NumberFormatFactory that supports a single locale. It can be visible or invisible.
\r
818 public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
\r
819 final Set<String> localeNames;
\r
820 final boolean visible;
\r
823 * Constructs a SimpleNumberFormatFactory with the given locale.
\r
826 public SimpleNumberFormatFactory(Locale locale) {
\r
827 this(locale, true);
\r
831 * Constructs a SimpleNumberFormatFactory with the given locale and the
\r
835 public SimpleNumberFormatFactory(Locale locale, boolean visible) {
\r
836 localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
\r
837 this.visible = visible;
\r
841 * Constructs a SimpleNumberFormatFactory with the given locale.
\r
844 public SimpleNumberFormatFactory(ULocale locale) {
\r
845 this(locale, true);
\r
849 * Constructs a SimpleNumberFormatFactory with the given locale and the
\r
853 public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
\r
854 localeNames = Collections.singleton(locale.getBaseName());
\r
855 this.visible = visible;
\r
862 public final boolean visible() {
\r
870 public final Set<String> getSupportedLocaleNames() {
\r
871 return localeNames;
\r
875 // shim so we can build without service code
\r
876 static abstract class NumberFormatShim {
\r
877 abstract Locale[] getAvailableLocales();
\r
878 abstract ULocale[] getAvailableULocales();
\r
879 abstract Object registerFactory(NumberFormatFactory f);
\r
880 abstract boolean unregister(Object k);
\r
881 abstract NumberFormat createInstance(ULocale l, int k);
\r
884 private static NumberFormatShim shim;
\r
885 private static NumberFormatShim getShim() {
\r
886 // Note: this instantiation is safe on loose-memory-model configurations
\r
887 // despite lack of synchronization, since the shim instance has no state--
\r
888 // it's all in the class init. The worst problem is we might instantiate
\r
889 // two shim instances, but they'll share the same state so that's ok.
\r
890 if (shim == null) {
\r
892 Class<?> cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");
\r
893 shim = (NumberFormatShim)cls.newInstance();
\r
896 catch (MissingResourceException e){
\r
899 catch (Exception e) {
\r
900 // e.printStackTrace();
\r
901 throw new RuntimeException(e.getMessage());
\r
909 * Returns the list of Locales for which NumberFormats are available.
\r
910 * @return the available locales
\r
913 public static Locale[] getAvailableLocales() {
\r
914 if (shim == null) {
\r
915 return ICUResourceBundle.getAvailableLocales();
\r
917 return getShim().getAvailableLocales();
\r
921 * {@icu} Returns the list of Locales for which NumberFormats are available.
\r
922 * @return the available locales
\r
923 * @draft ICU 3.2 (retain)
\r
924 * @provisional This API might change or be removed in a future release.
\r
926 public static ULocale[] getAvailableULocales() {
\r
927 if (shim == null) {
\r
928 return ICUResourceBundle.getAvailableULocales();
\r
930 return getShim().getAvailableULocales();
\r
934 * {@icu} Registers a new NumberFormatFactory. The factory is adopted by
\r
935 * the service and must not be modified. The returned object is a
\r
936 * key that can be used to unregister this factory.
\r
937 * @param factory the factory to register
\r
938 * @return a key with which to unregister the factory
\r
941 public static Object registerFactory(NumberFormatFactory factory) {
\r
942 if (factory == null) {
\r
943 throw new IllegalArgumentException("factory must not be null");
\r
945 return getShim().registerFactory(factory);
\r
949 * {@icu} Unregisters the factory or instance associated with this key (obtained from
\r
950 * registerInstance or registerFactory).
\r
951 * @param registryKey a key obtained from registerFactory
\r
952 * @return true if the object was successfully unregistered
\r
955 public static boolean unregister(Object registryKey) {
\r
956 if (registryKey == null) {
\r
957 throw new IllegalArgumentException("registryKey must not be null");
\r
960 if (shim == null) {
\r
964 return shim.unregister(registryKey);
\r
967 // ===== End of factory stuff =====
\r
970 * Overrides hashCode.
\r
973 public int hashCode() {
\r
974 return maximumIntegerDigits * 37 + maxFractionDigits;
\r
975 // just enough fields for a reasonable distribution
\r
979 * Overrides equals.
\r
980 * Two NumberFormats are equal if they are of the same class
\r
981 * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
\r
983 * @param obj the object to compare against
\r
984 * @return true if the object is equal to this.
\r
987 public boolean equals(Object obj) {
\r
988 if (obj == null) return false;
\r
991 if (getClass() != obj.getClass())
\r
993 NumberFormat other = (NumberFormat) obj;
\r
994 return maximumIntegerDigits == other.maximumIntegerDigits
\r
995 && minimumIntegerDigits == other.minimumIntegerDigits
\r
996 && maximumFractionDigits == other.maximumFractionDigits
\r
997 && minimumFractionDigits == other.minimumFractionDigits
\r
998 && groupingUsed == other.groupingUsed
\r
999 && parseIntegerOnly == other.parseIntegerOnly
\r
1000 && parseStrict == other.parseStrict;
\r
1004 * Overrides clone.
\r
1007 public Object clone() {
\r
1008 NumberFormat other = (NumberFormat) super.clone();
\r
1013 * Returns true if grouping is used in this format. For example, in the
\r
1014 * en_US locale, with grouping on, the number 1234567 will be formatted
\r
1015 * as "1,234,567". The grouping separator as well as the size of each group
\r
1016 * is locale-dependent and is determined by subclasses of NumberFormat.
\r
1017 * Grouping affects both parsing and formatting.
\r
1018 * @return true if grouping is used
\r
1019 * @see #setGroupingUsed
\r
1022 public boolean isGroupingUsed() {
\r
1023 return groupingUsed;
\r
1027 * Sets whether or not grouping will be used in this format. Grouping
\r
1028 * affects both parsing and formatting.
\r
1029 * @see #isGroupingUsed
\r
1030 * @param newValue true to use grouping.
\r
1033 public void setGroupingUsed(boolean newValue) {
\r
1034 groupingUsed = newValue;
\r
1038 * Returns the maximum number of digits allowed in the integer portion of a
\r
1039 * number. The default value is 40, which subclasses can override.
\r
1040 * When formatting, the exact behavior when this value is exceeded is
\r
1041 * subclass-specific. When parsing, this has no effect.
\r
1042 * @return the maximum number of integer digits
\r
1043 * @see #setMaximumIntegerDigits
\r
1046 public int getMaximumIntegerDigits() {
\r
1047 return maximumIntegerDigits;
\r
1051 * Sets the maximum number of digits allowed in the integer portion of a
\r
1052 * number. This must be >= minimumIntegerDigits. If the
\r
1053 * new value for maximumIntegerDigits is less than the current value
\r
1054 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
\r
1056 * @param newValue the maximum number of integer digits to be shown; if
\r
1057 * less than zero, then zero is used. Subclasses might enforce an
\r
1058 * upper limit to this value appropriate to the numeric type being formatted.
\r
1059 * @see #getMaximumIntegerDigits
\r
1062 public void setMaximumIntegerDigits(int newValue) {
\r
1063 maximumIntegerDigits = Math.max(0,newValue);
\r
1064 if (minimumIntegerDigits > maximumIntegerDigits)
\r
1065 minimumIntegerDigits = maximumIntegerDigits;
\r
1069 * Returns the minimum number of digits allowed in the integer portion of a
\r
1070 * number. The default value is 1, which subclasses can override.
\r
1071 * When formatting, if this value is not reached, numbers are padded on the
\r
1072 * left with the locale-specific '0' character to ensure at least this
\r
1073 * number of integer digits. When parsing, this has no effect.
\r
1074 * @return the minimum number of integer digits
\r
1075 * @see #setMinimumIntegerDigits
\r
1078 public int getMinimumIntegerDigits() {
\r
1079 return minimumIntegerDigits;
\r
1083 * Sets the minimum number of digits allowed in the integer portion of a
\r
1084 * number. This must be <= maximumIntegerDigits. If the
\r
1085 * new value for minimumIntegerDigits is more than the current value
\r
1086 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
\r
1088 * @param newValue the minimum number of integer digits to be shown; if
\r
1089 * less than zero, then zero is used. Subclasses might enforce an
\r
1090 * upper limit to this value appropriate to the numeric type being formatted.
\r
1091 * @see #getMinimumIntegerDigits
\r
1094 public void setMinimumIntegerDigits(int newValue) {
\r
1095 minimumIntegerDigits = Math.max(0,newValue);
\r
1096 if (minimumIntegerDigits > maximumIntegerDigits)
\r
1097 maximumIntegerDigits = minimumIntegerDigits;
\r
1101 * Returns the maximum number of digits allowed in the fraction
\r
1102 * portion of a number. The default value is 3, which subclasses
\r
1103 * can override. When formatting, the exact behavior when this
\r
1104 * value is exceeded is subclass-specific. When parsing, this has
\r
1106 * @return the maximum number of fraction digits
\r
1107 * @see #setMaximumFractionDigits
\r
1110 public int getMaximumFractionDigits() {
\r
1111 return maximumFractionDigits;
\r
1115 * Sets the maximum number of digits allowed in the fraction portion of a
\r
1116 * number. This must be >= minimumFractionDigits. If the
\r
1117 * new value for maximumFractionDigits is less than the current value
\r
1118 * of minimumFractionDigits, then minimumFractionDigits will also be set to
\r
1120 * @param newValue the maximum number of fraction digits to be shown; if
\r
1121 * less than zero, then zero is used. The concrete subclass may enforce an
\r
1122 * upper limit to this value appropriate to the numeric type being formatted.
\r
1123 * @see #getMaximumFractionDigits
\r
1126 public void setMaximumFractionDigits(int newValue) {
\r
1127 maximumFractionDigits = Math.max(0,newValue);
\r
1128 if (maximumFractionDigits < minimumFractionDigits)
\r
1129 minimumFractionDigits = maximumFractionDigits;
\r
1133 * Returns the minimum number of digits allowed in the fraction portion of a
\r
1134 * number. The default value is 0, which subclasses can override.
\r
1135 * When formatting, if this value is not reached, numbers are padded on
\r
1136 * the right with the locale-specific '0' character to ensure at least
\r
1137 * this number of fraction digits. When parsing, this has no effect.
\r
1138 * @return the minimum number of fraction digits
\r
1139 * @see #setMinimumFractionDigits
\r
1142 public int getMinimumFractionDigits() {
\r
1143 return minimumFractionDigits;
\r
1147 * Sets the minimum number of digits allowed in the fraction portion of a
\r
1148 * number. This must be <= maximumFractionDigits. If the
\r
1149 * new value for minimumFractionDigits exceeds the current value
\r
1150 * of maximumFractionDigits, then maximumFractionDigits will also be set to
\r
1152 * @param newValue the minimum number of fraction digits to be shown; if
\r
1153 * less than zero, then zero is used. Subclasses might enforce an
\r
1154 * upper limit to this value appropriate to the numeric type being formatted.
\r
1155 * @see #getMinimumFractionDigits
\r
1158 public void setMinimumFractionDigits(int newValue) {
\r
1159 minimumFractionDigits = Math.max(0,newValue);
\r
1160 if (maximumFractionDigits < minimumFractionDigits)
\r
1161 maximumFractionDigits = minimumFractionDigits;
\r
1165 * Sets the <tt>Currency</tt> object used to display currency
\r
1166 * amounts. This takes effect immediately, if this format is a
\r
1167 * currency format. If this format is not a currency format, then
\r
1168 * the currency object is used if and when this object becomes a
\r
1169 * currency format.
\r
1170 * @param theCurrency new currency object to use. May be null for
\r
1171 * some subclasses.
\r
1174 public void setCurrency(Currency theCurrency) {
\r
1175 currency = theCurrency;
\r
1179 * Returns the <tt>Currency</tt> object used to display currency
\r
1180 * amounts. This may be null.
\r
1183 public Currency getCurrency() {
\r
1188 * Returns the currency in effect for this formatter. Subclasses
\r
1189 * should override this method as needed. Unlike getCurrency(),
\r
1190 * this method should never return null.
\r
1191 * @return a non-null Currency
\r
1193 * @deprecated This API is ICU internal only.
\r
1195 protected Currency getEffectiveCurrency() {
\r
1196 Currency c = getCurrency();
\r
1198 ULocale uloc = getLocale(ULocale.VALID_LOCALE);
\r
1199 if (uloc == null) {
\r
1200 uloc = ULocale.getDefault();
\r
1202 c = Currency.getInstance(uloc);
\r
1208 * Returns the rounding mode used in this NumberFormat. The default implementation of
\r
1209 * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
\r
1210 * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
\r
1211 * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
\r
1212 * @see #setRoundingMode(int)
\r
1215 public int getRoundingMode() {
\r
1216 throw new UnsupportedOperationException(
\r
1217 "getRoundingMode must be implemented by the subclass implementation.");
\r
1221 * Set the rounding mode used in this NumberFormat. The default implementation of
\r
1222 * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
\r
1223 * @param roundingMode A rounding mode, between
\r
1224 * <code>BigDecimal.ROUND_UP</code> and
\r
1225 * <code>BigDecimal.ROUND_UNNECESSARY</code>.
\r
1226 * @see #getRoundingMode()
\r
1229 public void setRoundingMode(int roundingMode) {
\r
1230 throw new UnsupportedOperationException(
\r
1231 "setRoundingMode must be implemented by the subclass implementation.");
\r
1236 * Returns a specific style number format for a specific locale.
\r
1237 * @param desiredLocale the specific locale.
\r
1238 * @param choice number format style
\r
1239 * @throws IllegalArgumentException if choice is not one of
\r
1240 * NUMBERSTYLE, CURRENCYSTYLE,
\r
1241 * PERCENTSTYLE, SCIENTIFICSTYLE,
\r
1243 * ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,
\r
1246 public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
\r
1247 if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE) {
\r
1248 throw new IllegalArgumentException(
\r
1249 "choice should be from NUMBERSTYLE to PLURALCURRENCYSTYLE");
\r
1251 // if (shim == null) {
\r
1252 // return createInstance(desiredLocale, choice);
\r
1254 // // TODO: shims must call setLocale() on object they create
\r
1255 // return getShim().createInstance(desiredLocale, choice);
\r
1257 return getShim().createInstance(desiredLocale, choice);
\r
1260 // =======================privates===============================
\r
1261 // Hook for service
\r
1262 static NumberFormat createInstance(ULocale desiredLocale, int choice) {
\r
1263 // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single
\r
1264 // pattern, it is a pattern set, so we do not need to get them here.
\r
1265 // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency
\r
1266 // pattern in the locale but by replacing the single currency sign
\r
1267 // with double currency sign.
\r
1268 String pattern = getPattern(desiredLocale, choice);
\r
1269 DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
\r
1271 // Here we assume that the locale passed in is in the canonical
\r
1272 // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
\r
1273 // This style wont work for currency plural format.
\r
1274 // For currency plural format, the pattern is get from
\r
1275 // the locale (from CurrencyUnitPatterns) without override.
\r
1276 if(choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE){
\r
1277 String temp = symbols.getCurrencyPattern();
\r
1283 // replace single currency sign in the pattern with double currency sign
\r
1284 // if the choice is ISOCURRENCYSTYLE.
\r
1285 if (choice == ISOCURRENCYSTYLE) {
\r
1286 pattern = pattern.replace("\u00A4", doubleCurrencyStr);
\r
1289 // Get the numbering system
\r
1290 NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);
\r
1291 if ( ns == null ) {
\r
1295 NumberFormat format;
\r
1297 if ( ns != null && ns.isAlgorithmic()) {
\r
1299 String nsRuleSetGroup;
\r
1300 String nsRuleSetName;
\r
1302 int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;
\r
1304 nsDesc = ns.getDescription();
\r
1305 int firstSlash = nsDesc.indexOf("/");
\r
1306 int lastSlash = nsDesc.lastIndexOf("/");
\r
1308 if ( lastSlash > firstSlash ) {
\r
1309 String nsLocID = nsDesc.substring(0,firstSlash);
\r
1310 nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);
\r
1311 nsRuleSetName = nsDesc.substring(lastSlash+1);
\r
1313 nsLoc = new ULocale(nsLocID);
\r
1314 if ( nsRuleSetGroup.equals("SpelloutRules")) {
\r
1315 desiredRulesType = RuleBasedNumberFormat.SPELLOUT;
\r
1318 nsLoc = desiredLocale;
\r
1319 nsRuleSetName = nsDesc;
\r
1322 RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);
\r
1323 r.setDefaultRuleSet(nsRuleSetName);
\r
1326 DecimalFormat f = new DecimalFormat(pattern, symbols, choice);
\r
1327 // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
\r
1330 Add codes for the new method getIntegerInstance() [Richard/GCL]
\r
1332 // TODO: revisit this -- this is almost certainly not the way we want
\r
1333 // to do this. aliu 1/6/2004
\r
1334 if (choice == INTEGERSTYLE) {
\r
1335 f.setMaximumFractionDigits(0);
\r
1336 f.setDecimalSeparatorAlwaysShown(false);
\r
1337 f.setParseIntegerOnly(true);
\r
1341 // TODO: the actual locale of the *pattern* may differ from that
\r
1342 // for the *symbols*. For now, we use the data for the symbols.
\r
1344 ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
\r
1345 ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
\r
1346 format.setLocale(valid, actual);
\r
1352 * Returns the pattern for the provided locale and choice.
\r
1353 * @param forLocale the locale of the data.
\r
1354 * @param choice the pattern format.
\r
1355 * @return the pattern
\r
1356 * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
\r
1358 protected static String getPattern(Locale forLocale, int choice) {
\r
1359 return getPattern(ULocale.forLocale(forLocale), choice);
\r
1363 * Returns the pattern for the provided locale and choice.
\r
1364 * @param forLocale the locale of the data.
\r
1365 * @param choice the pattern format.
\r
1366 * @return the pattern
\r
1369 protected static String getPattern(ULocale forLocale, int choice) {
\r
1371 /* The following code takes care of a few cases where the
\r
1372 * resource data in the underlying JDK lags the new features
\r
1373 * we have added to ICU4J: scientific notation, rounding, and
\r
1374 * secondary grouping.
\r
1376 * We detect these cases here and return various hard-coded
\r
1377 * resource data. This is the simplest solution for now, but
\r
1378 * it is not a good long-term mechanism.
\r
1380 * We should replace this code with a data-driven mechanism
\r
1381 * that reads the bundle com.ibm.icu.impl.data.LocaleElements
\r
1382 * and parses an exception table that overrides the standard
\r
1383 * data at java.text.resource.LocaleElements*.java.
\r
1384 * Alternatively, we should create our own copy of the
\r
1385 * resource data, and use that exclusively.
\r
1388 // TEMPORARY, until we get scientific patterns into the main
\r
1389 // resources: Retrieve scientific patterns from our resources.
\r
1390 if (choice == SCIENTIFICSTYLE) {
\r
1391 // Temporarily hard code; retrieve from resource later
\r
1392 /*For ICU compatibility [Richard/GCL]*/
\r
1394 // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];
\r
1396 // TEMPORARY: Use rounding for Swiss currency
\r
1397 //if (choice == CURRENCYSTYLE &&
\r
1398 // forLocale.getCountry().equals("CH")) {
\r
1399 // return "'Fr. '#,##0.05;'Fr.-'#,##0.05";
\r
1401 // TEMPORARY: Special case IN number format
\r
1402 //if (choice == NUMBERSTYLE &&
\r
1403 // forLocale.getCountry().equals("IN")) {
\r
1404 // return "#,##,##0.###";
\r
1408 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
\r
1409 getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
\r
1410 String[] numberPatterns = rb.getStringArray("NumberPatterns");
\r
1413 // Try the cache first
\r
1414 String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);
\r
1415 if (numberPatterns == null) {
\r
1416 OverlayBundle resource = new OverlayBundle(new String[]
\r
1417 { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);
\r
1418 numberPatterns = resource.getStringArray("NumberPatterns");
\r
1419 // Update the cache
\r
1420 cachedLocaleData.put(forLocale, numberPatterns);
\r
1425 Add codes for the new method getIntegerInstance() [Richard/GCL]
\r
1427 /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,
\r
1428 * the pattern is the same as the pattern of CURRENCYSTYLE
\r
1429 * but by replacing the single currency sign with
\r
1430 * double currency sign or triple currency sign.
\r
1432 int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE :
\r
1433 ((choice == ISOCURRENCYSTYLE || choice == PLURALCURRENCYSTYLE)?
\r
1434 CURRENCYSTYLE : choice); //[Richard/GCL]
\r
1435 return numberPatterns[entry]; //[Richard/GCL]
\r
1439 * First, read in the default serializable data.
\r
1441 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
\r
1442 * the stream was written by JDK 1.1,
\r
1443 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
\r
1444 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
\r
1445 * since the <code>int</code> fields were not present in JDK 1.1.
\r
1446 * Finally, set serialVersionOnStream back to the maximum allowed value so that
\r
1447 * default serialization will work properly if this object is streamed out again.
\r
1449 private void readObject(ObjectInputStream stream)
\r
1450 throws IOException, ClassNotFoundException
\r
1452 stream.defaultReadObject();
\r
1454 // we don't have serialization data for this format
\r
1455 if (serialVersionOnStream < 1) {
\r
1456 // Didn't have additional int fields, reassign to use them.
\r
1457 maximumIntegerDigits = maxIntegerDigits;
\r
1458 minimumIntegerDigits = minIntegerDigits;
\r
1459 maximumFractionDigits = maxFractionDigits;
\r
1460 minimumFractionDigits = minFractionDigits;
\r
1464 Validate the min and max fields [Richard/GCL]
\r
1466 if (minimumIntegerDigits > maximumIntegerDigits ||
\r
1467 minimumFractionDigits > maximumFractionDigits ||
\r
1468 minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
\r
1469 throw new InvalidObjectException("Digit count range invalid");
\r
1471 serialVersionOnStream = currentSerialVersion;
\r
1475 * Write out the default serializable data, after first setting
\r
1476 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
\r
1477 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
\r
1478 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
\r
1479 * with the JDK 1.1 version of the stream format.
\r
1481 private void writeObject(ObjectOutputStream stream)
\r
1482 throws IOException
\r
1484 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
\r
1485 (byte)maximumIntegerDigits;
\r
1486 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
\r
1487 (byte)minimumIntegerDigits;
\r
1488 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
\r
1489 (byte)maximumFractionDigits;
\r
1490 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
\r
1491 (byte)minimumFractionDigits;
\r
1492 stream.defaultWriteObject();
\r
1495 // Unused -- Alan 2003-05
\r
1497 // * Cache to hold the NumberPatterns of a Locale.
\r
1499 // private static final Hashtable cachedLocaleData = new Hashtable(3);
\r
1501 private static final char[] doubleCurrencySign = {0xA4, 0xA4};
\r
1502 private static final String doubleCurrencyStr = new String(doubleCurrencySign);
\r
1505 Add Field for the new method getIntegerInstance() [Richard/GCL]
\r
1510 * True if the the grouping (i.e. thousands) separator is used when
\r
1511 * formatting and parsing numbers.
\r
1514 * @see #isGroupingUsed
\r
1516 private boolean groupingUsed = true;
\r
1519 * The maximum number of digits allowed in the integer portion of a
\r
1520 * number. <code>maxIntegerDigits</code> must be greater than or equal to
\r
1521 * <code>minIntegerDigits</code>.
\r
1523 * <strong>Note:</strong> This field exists only for serialization
\r
1524 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
\r
1525 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
\r
1526 * When writing to a stream, <code>maxIntegerDigits</code> is set to
\r
1527 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
\r
1528 * whichever is smaller. When reading from a stream, this field is used
\r
1529 * only if <code>serialVersionOnStream</code> is less than 1.
\r
1532 * @see #getMaximumIntegerDigits
\r
1534 private byte maxIntegerDigits = 40;
\r
1537 * The minimum number of digits allowed in the integer portion of a
\r
1538 * number. <code>minimumIntegerDigits</code> must be less than or equal to
\r
1539 * <code>maximumIntegerDigits</code>.
\r
1541 * <strong>Note:</strong> This field exists only for serialization
\r
1542 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
\r
1543 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
\r
1544 * When writing to a stream, <code>minIntegerDigits</code> is set to
\r
1545 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
\r
1546 * whichever is smaller. When reading from a stream, this field is used
\r
1547 * only if <code>serialVersionOnStream</code> is less than 1.
\r
1550 * @see #getMinimumIntegerDigits
\r
1552 private byte minIntegerDigits = 1;
\r
1555 * The maximum number of digits allowed in the fractional portion of a
\r
1556 * number. <code>maximumFractionDigits</code> must be greater than or equal to
\r
1557 * <code>minimumFractionDigits</code>.
\r
1559 * <strong>Note:</strong> This field exists only for serialization
\r
1560 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
\r
1561 * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
\r
1562 * When writing to a stream, <code>maxFractionDigits</code> is set to
\r
1563 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
\r
1564 * whichever is smaller. When reading from a stream, this field is used
\r
1565 * only if <code>serialVersionOnStream</code> is less than 1.
\r
1568 * @see #getMaximumFractionDigits
\r
1570 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
\r
1573 * The minimum number of digits allowed in the fractional portion of a
\r
1574 * number. <code>minimumFractionDigits</code> must be less than or equal to
\r
1575 * <code>maximumFractionDigits</code>.
\r
1577 * <strong>Note:</strong> This field exists only for serialization
\r
1578 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
\r
1579 * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
\r
1580 * When writing to a stream, <code>minFractionDigits</code> is set to
\r
1581 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
\r
1582 * whichever is smaller. When reading from a stream, this field is used
\r
1583 * only if <code>serialVersionOnStream</code> is less than 1.
\r
1586 * @see #getMinimumFractionDigits
\r
1588 private byte minFractionDigits = 0;
\r
1591 * True if this format will parse numbers as integers only.
\r
1594 * @see #isParseIntegerOnly
\r
1596 private boolean parseIntegerOnly = false;
\r
1598 // new fields for 1.2. byte is too small for integer digits.
\r
1601 * The maximum number of digits allowed in the integer portion of a
\r
1602 * number. <code>maximumIntegerDigits</code> must be greater than or equal to
\r
1603 * <code>minimumIntegerDigits</code>.
\r
1606 * @see #getMaximumIntegerDigits
\r
1608 private int maximumIntegerDigits = 40;
\r
1611 * The minimum number of digits allowed in the integer portion of a
\r
1612 * number. <code>minimumIntegerDigits</code> must be less than or equal to
\r
1613 * <code>maximumIntegerDigits</code>.
\r
1616 * @see #getMinimumIntegerDigits
\r
1618 private int minimumIntegerDigits = 1;
\r
1621 * The maximum number of digits allowed in the fractional portion of a
\r
1622 * number. <code>maximumFractionDigits</code> must be greater than or equal to
\r
1623 * <code>minimumFractionDigits</code>.
\r
1626 * @see #getMaximumFractionDigits
\r
1628 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
\r
1631 * The minimum number of digits allowed in the fractional portion of a
\r
1632 * number. <code>minimumFractionDigits</code> must be less than or equal to
\r
1633 * <code>maximumFractionDigits</code>.
\r
1636 * @see #getMinimumFractionDigits
\r
1638 private int minimumFractionDigits = 0;
\r
1641 * Currency object used to format currencies. Subclasses may
\r
1642 * ignore this if they are not currency formats. This will be
\r
1643 * null unless a subclass sets it to a non-null value.
\r
1646 private Currency currency;
\r
1648 static final int currentSerialVersion = 1;
\r
1651 * Describes the version of <code>NumberFormat</code> present on the stream.
\r
1652 * Possible values are:
\r
1654 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
\r
1655 * In this version, the <code>int</code> fields such as
\r
1656 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
\r
1657 * fields such as <code>maxIntegerDigits</code> are used instead.
\r
1659 * <li><b>1</b>: the JDK 1.2 version of the stream format. The values of the
\r
1660 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
\r
1661 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
\r
1662 * are used instead.
\r
1664 * When streaming out a <code>NumberFormat</code>, the most recent format
\r
1665 * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
\r
1666 * is always written.
\r
1670 private int serialVersionOnStream = currentSerialVersion;
\r
1672 // Removed "implements Cloneable" clause. Needs to update serialization
\r
1673 // ID for backward compatibility.
\r
1674 private static final long serialVersionUID = -2308460125733713944L;
\r
1677 * Empty constructor. Public for compatibily with JDK which lets the
\r
1678 * compiler generate a default public constructor even though this is
\r
1679 * an abstract class.
\r
1682 public NumberFormat() {
\r
1685 // new in ICU4J 3.6
\r
1686 private boolean parseStrict;
\r
1689 * The instances of this inner class are used as attribute keys and values
\r
1690 * in AttributedCharacterIterator that
\r
1691 * NumberFormat.formatToCharacterIterator() method returns.
\r
1693 * There is no public constructor to this class, the only instances are the
\r
1694 * constants defined here.
\r
1698 public static class Field extends Format.Field {
\r
1699 // generated by serialver from JDK 1.4.1_01
\r
1700 static final long serialVersionUID = -4516273749929385842L;
\r
1705 public static final Field SIGN = new Field("sign");
\r
1710 public static final Field INTEGER = new Field("integer");
\r
1715 public static final Field FRACTION = new Field("fraction");
\r
1720 public static final Field EXPONENT = new Field("exponent");
\r
1725 public static final Field EXPONENT_SIGN = new Field("exponent sign");
\r
1730 public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
\r
1735 public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
\r
1739 public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
\r
1744 public static final Field PERCENT = new Field("percent");
\r
1749 public static final Field PERMILLE = new Field("per mille");
\r
1754 public static final Field CURRENCY = new Field("currency");
\r
1757 * Constructs a new instance of NumberFormat.Field with the given field
\r
1761 protected Field(String fieldName) {
\r
1766 * serizalization method resolve instances to the constant
\r
1767 * NumberFormat.Field values
\r
1770 protected Object readResolve() throws InvalidObjectException {
\r
1771 if (this.getName().equals(INTEGER.getName()))
\r
1773 if (this.getName().equals(FRACTION.getName()))
\r
1775 if (this.getName().equals(EXPONENT.getName()))
\r
1777 if (this.getName().equals(EXPONENT_SIGN.getName()))
\r
1778 return EXPONENT_SIGN;
\r
1779 if (this.getName().equals(EXPONENT_SYMBOL.getName()))
\r
1780 return EXPONENT_SYMBOL;
\r
1781 if (this.getName().equals(CURRENCY.getName()))
\r
1783 if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
\r
1784 return DECIMAL_SEPARATOR;
\r
1785 if (this.getName().equals(GROUPING_SEPARATOR.getName()))
\r
1786 return GROUPING_SEPARATOR;
\r
1787 if (this.getName().equals(PERCENT.getName()))
\r
1789 if (this.getName().equals(PERMILLE.getName()))
\r
1791 if (this.getName().equals(SIGN.getName()))
\r
1794 throw new InvalidObjectException("An invalid object.");
\r