2 *******************************************************************************
3 * Copyright (C) 1996-2013, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
8 package com.ibm.icu.text;
10 import java.io.IOException;
11 import java.io.InvalidObjectException;
12 import java.io.ObjectInputStream;
13 import java.io.ObjectOutputStream;
14 import java.math.BigInteger;
15 import java.text.FieldPosition;
16 import java.text.Format;
17 import java.text.ParseException;
18 import java.text.ParsePosition;
19 import java.util.Collections;
20 import java.util.Locale;
21 import java.util.MissingResourceException;
24 import com.ibm.icu.impl.ICUResourceBundle;
25 import com.ibm.icu.util.Currency;
26 import com.ibm.icu.util.CurrencyAmount;
27 import com.ibm.icu.util.ULocale;
28 import com.ibm.icu.util.ULocale.Category;
29 import com.ibm.icu.util.UResourceBundle;
32 * {@icuenhanced java.text.NumberFormat}.{@icu _usage_}
34 * <code>NumberFormat</code> is the abstract base class for all number
35 * formats. This class provides the interface for formatting and parsing
36 * numbers. <code>NumberFormat</code> also provides methods for determining
37 * which locales have number formats, and what their names are.
39 * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
40 * Your code can be completely independent of the locale conventions for
41 * decimal points, thousands-separators, or even the particular decimal
42 * digits used, or whether the number format is even decimal.
45 * To format a number for the current Locale, use one of the factory
49 * myString = NumberFormat.getInstance().format(myNumber);
52 * If you are formatting multiple numbers, it is
53 * more efficient to get the format and use it multiple times so that
54 * the system doesn't have to fetch the information about the local
55 * language and country conventions multiple times.
58 * NumberFormat nf = NumberFormat.getInstance();
59 * for (int i = 0; i < a.length; ++i) {
60 * output.println(nf.format(myNumber[i]) + "; ");
64 * To format a number for a different Locale, specify it in the
65 * call to <code>getInstance</code>.
68 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
71 * You can also use a <code>NumberFormat</code> to parse numbers:
74 * myNumber = nf.parse(myString);
77 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
78 * normal number format. Use <code>getIntegerInstance</code> to get an
79 * integer number format. Use <code>getCurrencyInstance</code> to get the
80 * currency number format. And use <code>getPercentInstance</code> to get a
81 * format for displaying percentages. Some factory methods are found within
82 * subclasses of NumberFormat. With this format, a fraction like
83 * 0.53 is displayed as 53%.
86 * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
87 * as parameter to get the correct instance.
89 * use getInstance(...NUMBERSTYLE) to get the normal number format,
90 * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
91 * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
92 * getInstance(...INTEGERSTYLE) to get an integer number format,
93 * getInstance(...CURRENCYSTYLE) to get the currency number format,
94 * in which the currency is represented by its symbol, for example, "$3.00".
95 * getInstance(...ISOCURRENCYSTYLE) to get the currency number format,
96 * in which the currency is represented by its ISO code, for example "USD3.00".
97 * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
98 * in which the currency is represented by its full name in plural format,
99 * for example, "3.00 US dollars" or "1.00 US dollar".
103 * You can also control the display of numbers with such methods as
104 * <code>setMinimumFractionDigits</code>.
105 * If you want even more control over the format or parsing,
106 * or want to give your users more control,
107 * you can try casting the <code>NumberFormat</code> you get from the factory methods
108 * to a <code>DecimalFormat</code>. This will work for the vast majority
109 * of locales; just remember to put it in a <code>try</code> block in case you
110 * encounter an unusual one.
113 * NumberFormat is designed such that some controls
114 * work for formatting and others work for parsing. The following is
115 * the detailed description for each these control methods,
117 * setParseIntegerOnly : only affects parsing, e.g.
118 * if true, "3456.78" -> 3456 (and leaves the parse position just after '6')
119 * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')
120 * This is independent of formatting. If you want to not show a decimal point
121 * where there might be no digits after the decimal point, use
122 * setDecimalSeparatorAlwaysShown on DecimalFormat.
124 * You can also use forms of the <code>parse</code> and <code>format</code>
125 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
128 * <li> progressively parse through pieces of a string
129 * <li> align the decimal point and other areas
131 * For example, you can align numbers in two ways:
133 * <li> If you are using a monospaced font with spacing for alignment,
134 * you can pass the <code>FieldPosition</code> in your format call, with
135 * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
136 * <code>getEndIndex</code> will be set to the offset between the
137 * last character of the integer and the decimal. Add
138 * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
140 * <li> If you are using proportional fonts,
141 * instead of padding with spaces, measure the width
142 * of the string in pixels from the start to <code>getEndIndex</code>.
143 * Then move the pen by
144 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
145 * It also works where there is no decimal, but possibly additional
146 * characters at the end, e.g., with parentheses in negative
147 * numbers: "(12)" for -12.
150 * <h4>Synchronization</h4>
152 * Number formats are generally not synchronized. It is recommended to create
153 * separate format instances for each thread. If multiple threads access a format
154 * concurrently, it must be synchronized externally.
157 * <h4>DecimalFormat</h4>
158 * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
159 * NumberFormat API is essentially an abstraction from DecimalFormat's API.
160 * Refer to DecimalFormat for more information about this API.</p>
163 * see java.text.ChoiceFormat
165 * @author Helena Shih
169 public abstract class NumberFormat extends UFormat {
172 * {@icu} Constant to specify normal number style of format.
175 public static final int NUMBERSTYLE = 0;
177 * {@icu} Constant to specify currency style of format which uses currency symbol
178 * to represent currency, for example: "$3.00".
181 public static final int CURRENCYSTYLE = 1;
183 * {@icu} Constant to specify a style of format to display percent.
186 public static final int PERCENTSTYLE = 2;
188 * {@icu} Constant to specify a style of format to display scientific number.
191 public static final int SCIENTIFICSTYLE = 3;
193 * {@icu} Constant to specify a integer number style format.
196 public static final int INTEGERSTYLE = 4;
198 * {@icu} Constant to specify currency style of format which uses currency
199 * ISO code to represent currency, for example: "USD3.00".
202 public static final int ISOCURRENCYSTYLE = 5;
204 * {@icu} Constant to specify currency style of format which uses currency
205 * long name with plural format to represent currency, for example,
209 public static final int PLURALCURRENCYSTYLE = 6;
212 * Field constant used to construct a FieldPosition object. Signifies that
213 * the position of the integer part of a formatted number should be returned.
214 * @see java.text.FieldPosition
217 public static final int INTEGER_FIELD = 0;
220 * Field constant used to construct a FieldPosition object. Signifies that
221 * the position of the fraction part of a formatted number should be returned.
222 * @see java.text.FieldPosition
225 public static final int FRACTION_FIELD = 1;
228 * Formats a number and appends the resulting text to the given string buffer.
229 * {@icunote} recognizes <code>BigInteger</code>
230 * and <code>BigDecimal</code> objects.
231 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
235 public StringBuffer format(Object number,
236 StringBuffer toAppendTo,
238 if (number instanceof Long) {
239 return format(((Long)number).longValue(), toAppendTo, pos);
240 } else if (number instanceof BigInteger) {
241 return format((BigInteger) number, toAppendTo, pos);
242 } else if (number instanceof java.math.BigDecimal) {
243 return format((java.math.BigDecimal) number, toAppendTo, pos);
244 } else if (number instanceof com.ibm.icu.math.BigDecimal) {
245 return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);
246 } else if (number instanceof CurrencyAmount) {
247 return format((CurrencyAmount)number, toAppendTo, pos);
248 } else if (number instanceof Number) {
249 return format(((Number)number).doubleValue(), toAppendTo, pos);
251 throw new IllegalArgumentException("Cannot format given Object as a Number");
256 * Parses text from a string to produce a number.
257 * @param source the String to parse
258 * @param parsePosition the position at which to start the parse
259 * @return the parsed number, or null
260 * @see java.text.NumberFormat#parseObject(String, ParsePosition)
264 public final Object parseObject(String source,
265 ParsePosition parsePosition) {
266 return parse(source, parsePosition);
270 * Specialization of format.
271 * @see java.text.Format#format(Object)
274 public final String format(double number) {
275 return format(number,new StringBuffer(),
276 new FieldPosition(0)).toString();
280 * Specialization of format.
281 * @see java.text.Format#format(Object)
284 public final String format(long number) {
285 StringBuffer buf = new StringBuffer(19);
286 FieldPosition pos = new FieldPosition(0);
287 format(number, buf, pos);
288 return buf.toString();
292 * {@icu} Convenience method to format a BigInteger.
295 public final String format(BigInteger number) {
296 return format(number, new StringBuffer(),
297 new FieldPosition(0)).toString();
301 * Convenience method to format a BigDecimal.
304 public final String format(java.math.BigDecimal number) {
305 return format(number, new StringBuffer(),
306 new FieldPosition(0)).toString();
310 * {@icu} Convenience method to format an ICU BigDecimal.
313 public final String format(com.ibm.icu.math.BigDecimal number) {
314 return format(number, new StringBuffer(),
315 new FieldPosition(0)).toString();
319 * {@icu} Convenience method to format a CurrencyAmount.
322 public final String format(CurrencyAmount currAmt) {
323 return format(currAmt, new StringBuffer(),
324 new FieldPosition(0)).toString();
328 * Specialization of format.
329 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
332 public abstract StringBuffer format(double number,
333 StringBuffer toAppendTo,
337 * Specialization of format.
338 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
341 public abstract StringBuffer format(long number,
342 StringBuffer toAppendTo,
345 * {@icu} Formats a BigInteger. Specialization of format.
346 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
349 public abstract StringBuffer format(BigInteger number,
350 StringBuffer toAppendTo,
353 * {@icu} Formats a BigDecimal. Specialization of format.
354 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
357 public abstract StringBuffer format(java.math.BigDecimal number,
358 StringBuffer toAppendTo,
361 * {@icu} Formats an ICU BigDecimal. Specialization of format.
362 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
365 public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,
366 StringBuffer toAppendTo,
369 * {@icu} Formats a CurrencyAmount. Specialization of format.
370 * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
373 public StringBuffer format(CurrencyAmount currAmt,
374 StringBuffer toAppendTo,
376 // Default implementation -- subclasses may override
377 Currency save = getCurrency(), curr = currAmt.getCurrency();
378 boolean same = curr.equals(save);
379 if (!same) setCurrency(curr);
380 format(currAmt.getNumber(), toAppendTo, pos);
381 if (!same) setCurrency(save);
386 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
387 * Long.MAX_VALUE] and with no decimals), otherwise a Double.
388 * If IntegerOnly is set, will stop at a decimal
389 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
391 * Does not throw an exception; if no object can be parsed, index is
393 * @see #isParseIntegerOnly
394 * @see java.text.Format#parseObject(String, ParsePosition)
397 public abstract Number parse(String text, ParsePosition parsePosition);
400 * Parses text from the beginning of the given string to produce a number.
401 * The method might not use the entire text of the given string.
403 * @param text A String whose beginning should be parsed.
404 * @return A Number parsed from the string.
405 * @throws ParseException if the beginning of the specified string
410 //Bug 4375399 [Richard/GCL]
411 public Number parse(String text) throws ParseException {
412 ParsePosition parsePosition = new ParsePosition(0);
413 Number result = parse(text, parsePosition);
414 if (parsePosition.getIndex() == 0) {
415 throw new ParseException("Unparseable number: \"" + text + '"',
416 parsePosition.getErrorIndex());
422 * Parses text from the given string as a CurrencyAmount. Unlike
423 * the parse() method, this method will attempt to parse a generic
424 * currency name, searching for a match of this object's locale's
425 * currency display names, or for a 3-letter ISO currency code.
426 * This method will fail if this format is not a currency format,
427 * that is, if it does not contain the currency pattern symbol
428 * (U+00A4) in its prefix or suffix.
430 * @param text the text to parse
431 * @param pos input-output position; on input, the position within
432 * text to match; must have 0 <= pos.getIndex() < text.length();
433 * on output, the position after the last matched character. If
434 * the parse fails, the position in unchanged upon output.
435 * @return a CurrencyAmount, or null upon failure
438 public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
440 // Default implementation only -- subclasses should override
441 Number n = parse(text.toString(), pos);
442 return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
447 * Returns true if this format will parse numbers as integers only.
448 * For example in the English locale, with ParseIntegerOnly true, the
449 * string "1234." would be parsed as the integer value 1234 and parsing
450 * would stop at the "." character. The decimal separator accepted
451 * by the parse operation is locale-dependent and determined by the
453 * @return true if this will parse integers only
456 public boolean isParseIntegerOnly() {
457 return parseIntegerOnly;
461 * Sets whether or not numbers should be parsed as integers only.
462 * @param value true if this should parse integers only
463 * @see #isParseIntegerOnly
466 public void setParseIntegerOnly(boolean value) {
467 parseIntegerOnly = value;
471 * {@icu} Sets whether strict parsing is in effect. When this is true, the
472 * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
473 * <li>Leading or doubled grouping separators<br>
474 * ',123' and '1,,234" fail</li>
475 * <li>Groups of incorrect length when grouping is used<br>
476 * '1,23' and '1234,567' fail, but '1234' passes</li>
477 * <li>Grouping separators used in numbers followed by exponents<br>
478 * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
479 * not followed by a number)</li>
481 * When strict parsing is off, all grouping separators are ignored.
482 * This is the default behavior.
483 * @param value True to enable strict parsing. Default is false.
484 * @see #isParseStrict
487 public void setParseStrict(boolean value) {
492 * {@icu} Returns whether strict parsing is in effect.
493 * @return true if strict parsing is in effect
494 * @see #setParseStrict
497 public boolean isParseStrict() {
501 //============== Locale Stuff =====================
504 * Returns the default number format for the current default <code>FORMAT</code> locale.
505 * The default format is one of the styles provided by the other
506 * factory methods: getNumberInstance, getIntegerInstance,
507 * getCurrencyInstance or getPercentInstance.
508 * Exactly which one is locale-dependent.
509 * @see Category#FORMAT
512 //Bug 4408066 [Richard/GCL]
513 public final static NumberFormat getInstance() {
514 return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
518 * Returns the default number format for the specified locale.
519 * The default format is one of the styles provided by the other
520 * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
521 * Exactly which one is locale-dependent.
524 public static NumberFormat getInstance(Locale inLocale) {
525 return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
529 * {@icu} Returns the default number format for the specified locale.
530 * The default format is one of the styles provided by the other
531 * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
532 * Exactly which one is locale-dependent.
535 public static NumberFormat getInstance(ULocale inLocale) {
536 return getInstance(inLocale, NUMBERSTYLE);
540 * {@icu} Returns a specific style number format for default <code>FORMAT</code> locale.
541 * @param style number format style
542 * @see Category#FORMAT
545 public final static NumberFormat getInstance(int style) {
546 return getInstance(ULocale.getDefault(Category.FORMAT), style);
550 * {@icu} Returns a specific style number format for a specific locale.
551 * @param inLocale the specific locale.
552 * @param style number format style
555 public static NumberFormat getInstance(Locale inLocale, int style) {
556 return getInstance(ULocale.forLocale(inLocale), style);
561 * Returns a general-purpose number format for the current default <code>FORMAT</code> locale.
562 * @see Category#FORMAT
565 public final static NumberFormat getNumberInstance() {
566 return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
570 * Returns a general-purpose number format for the specified locale.
573 public static NumberFormat getNumberInstance(Locale inLocale) {
574 return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
578 * {@icu} Returns a general-purpose number format for the specified locale.
581 public static NumberFormat getNumberInstance(ULocale inLocale) {
582 return getInstance(inLocale, NUMBERSTYLE);
586 * Returns an integer number format for the current default <code>FORMAT</code> locale. The
587 * returned number format is configured to round floating point numbers
588 * to the nearest integer using IEEE half-even rounding (see {@link
589 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
590 * and to parse only the integer part of an input string (see {@link
591 * #isParseIntegerOnly isParseIntegerOnly}).
593 * @return a number format for integer values
594 * @see Category#FORMAT
597 //Bug 4408066 [Richard/GCL]
598 public final static NumberFormat getIntegerInstance() {
599 return getInstance(ULocale.getDefault(Category.FORMAT), INTEGERSTYLE);
603 * Returns an integer number format for the specified locale. The
604 * returned number format is configured to round floating point numbers
605 * to the nearest integer using IEEE half-even rounding (see {@link
606 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
607 * and to parse only the integer part of an input string (see {@link
608 * #isParseIntegerOnly isParseIntegerOnly}).
610 * @param inLocale the locale for which a number format is needed
611 * @return a number format for integer values
614 //Bug 4408066 [Richard/GCL]
615 public static NumberFormat getIntegerInstance(Locale inLocale) {
616 return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
620 * {@icu} Returns an integer number format for the specified locale. The
621 * returned number format is configured to round floating point numbers
622 * to the nearest integer using IEEE half-even rounding (see {@link
623 * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
624 * and to parse only the integer part of an input string (see {@link
625 * #isParseIntegerOnly isParseIntegerOnly}).
627 * @param inLocale the locale for which a number format is needed
628 * @return a number format for integer values
631 public static NumberFormat getIntegerInstance(ULocale inLocale) {
632 return getInstance(inLocale, INTEGERSTYLE);
636 * Returns a currency format for the current default <code>FORMAT</code> locale.
637 * @return a number format for currency
638 * @see Category#FORMAT
641 public final static NumberFormat getCurrencyInstance() {
642 return getInstance(ULocale.getDefault(Category.FORMAT), CURRENCYSTYLE);
646 * Returns a currency format for the specified locale.
647 * @return a number format for currency
650 public static NumberFormat getCurrencyInstance(Locale inLocale) {
651 return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
655 * {@icu} Returns a currency format for the specified locale.
656 * @return a number format for currency
659 public static NumberFormat getCurrencyInstance(ULocale inLocale) {
660 return getInstance(inLocale, CURRENCYSTYLE);
664 * Returns a percentage format for the current default <code>FORMAT</code> locale.
665 * @return a number format for percents
666 * @see Category#FORMAT
669 public final static NumberFormat getPercentInstance() {
670 return getInstance(ULocale.getDefault(Category.FORMAT), PERCENTSTYLE);
674 * Returns a percentage format for the specified locale.
675 * @return a number format for percents
678 public static NumberFormat getPercentInstance(Locale inLocale) {
679 return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
683 * {@icu} Returns a percentage format for the specified locale.
684 * @return a number format for percents
687 public static NumberFormat getPercentInstance(ULocale inLocale) {
688 return getInstance(inLocale, PERCENTSTYLE);
692 * {@icu} Returns a scientific format for the current default <code>FORMAT</code> locale.
693 * @return a scientific number format
694 * @see Category#FORMAT
697 public final static NumberFormat getScientificInstance() {
698 return getInstance(ULocale.getDefault(Category.FORMAT), SCIENTIFICSTYLE);
702 * {@icu} Returns a scientific format for the specified locale.
703 * @return a scientific number format
706 public static NumberFormat getScientificInstance(Locale inLocale) {
707 return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
711 * {@icu} Returns a scientific format for the specified locale.
712 * @return a scientific number format
715 public static NumberFormat getScientificInstance(ULocale inLocale) {
716 return getInstance(inLocale, SCIENTIFICSTYLE);
719 // ===== Factory stuff =====
721 * A NumberFormatFactory is used to register new number formats. The factory
722 * should be able to create any of the predefined formats for each locale it
723 * supports. When registered, the locales it supports extend or override the
724 * locales already supported by ICU.
726 * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
727 * ULocale instead of Locale. Instead of overriding createFormat(Locale, int),
728 * new implementations should override createFactory(ULocale, int). Note that
729 * one of these two methods <b>MUST</b> be overridden or else an infinite
734 public static abstract class NumberFormatFactory {
736 * Value passed to format requesting a default number format.
739 public static final int FORMAT_NUMBER = NUMBERSTYLE;
742 * Value passed to format requesting a currency format.
745 public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
748 * Value passed to format requesting a percent format.
751 public static final int FORMAT_PERCENT = PERCENTSTYLE;
754 * Value passed to format requesting a scientific format.
757 public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
760 * Value passed to format requesting an integer format.
763 public static final int FORMAT_INTEGER = INTEGERSTYLE;
766 * Returns true if this factory is visible. Default is true.
767 * If not visible, the locales supported by this factory will not
768 * be listed by getAvailableLocales. This value must not change.
769 * @return true if the factory is visible.
772 public boolean visible() {
777 * Returns an immutable collection of the locale names directly
778 * supported by this factory.
779 * @return the supported locale names.
782 public abstract Set<String> getSupportedLocaleNames();
785 * Returns a number format of the appropriate type. If the locale
786 * is not supported, return null. If the locale is supported, but
787 * the type is not provided by this service, return null. Otherwise
788 * return an appropriate instance of NumberFormat.
789 * <b>Note:</b> as of ICU4J 3.2, implementations should override
790 * this method instead of createFormat(Locale, int).
791 * @param loc the locale for which to create the format
792 * @param formatType the type of format
793 * @return the NumberFormat, or null.
796 public NumberFormat createFormat(ULocale loc, int formatType) {
797 return createFormat(loc.toLocale(), formatType);
801 * Returns a number format of the appropriate type. If the locale
802 * is not supported, return null. If the locale is supported, but
803 * the type is not provided by this service, return null. Otherwise
804 * return an appropriate instance of NumberFormat.
805 * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
806 * overridden instead of this method. This method is no longer
807 * abstract and delegates to that method.
808 * @param loc the locale for which to create the format
809 * @param formatType the type of format
810 * @return the NumberFormat, or null.
813 public NumberFormat createFormat(Locale loc, int formatType) {
814 return createFormat(ULocale.forLocale(loc), formatType);
820 protected NumberFormatFactory() {
825 * A NumberFormatFactory that supports a single locale. It can be visible or invisible.
828 public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
829 final Set<String> localeNames;
830 final boolean visible;
833 * Constructs a SimpleNumberFormatFactory with the given locale.
836 public SimpleNumberFormatFactory(Locale locale) {
841 * Constructs a SimpleNumberFormatFactory with the given locale and the
845 public SimpleNumberFormatFactory(Locale locale, boolean visible) {
846 localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
847 this.visible = visible;
851 * Constructs a SimpleNumberFormatFactory with the given locale.
854 public SimpleNumberFormatFactory(ULocale locale) {
859 * Constructs a SimpleNumberFormatFactory with the given locale and the
863 public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
864 localeNames = Collections.singleton(locale.getBaseName());
865 this.visible = visible;
873 public final boolean visible() {
882 public final Set<String> getSupportedLocaleNames() {
887 // shim so we can build without service code
888 static abstract class NumberFormatShim {
889 abstract Locale[] getAvailableLocales();
890 abstract ULocale[] getAvailableULocales();
891 abstract Object registerFactory(NumberFormatFactory f);
892 abstract boolean unregister(Object k);
893 abstract NumberFormat createInstance(ULocale l, int k);
896 private static NumberFormatShim shim;
897 private static NumberFormatShim getShim() {
898 // Note: this instantiation is safe on loose-memory-model configurations
899 // despite lack of synchronization, since the shim instance has no state--
900 // it's all in the class init. The worst problem is we might instantiate
901 // two shim instances, but they'll share the same state so that's ok.
904 Class<?> cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");
905 shim = (NumberFormatShim)cls.newInstance();
908 catch (MissingResourceException e){
911 catch (Exception e) {
912 // e.printStackTrace();
913 throw new RuntimeException(e.getMessage());
921 * Returns the list of Locales for which NumberFormats are available.
922 * @return the available locales
925 public static Locale[] getAvailableLocales() {
927 return ICUResourceBundle.getAvailableLocales();
929 return getShim().getAvailableLocales();
933 * {@icu} Returns the list of Locales for which NumberFormats are available.
934 * @return the available locales
935 * @draft ICU 3.2 (retain)
936 * @provisional This API might change or be removed in a future release.
938 public static ULocale[] getAvailableULocales() {
940 return ICUResourceBundle.getAvailableULocales();
942 return getShim().getAvailableULocales();
946 * {@icu} Registers a new NumberFormatFactory. The factory is adopted by
947 * the service and must not be modified. The returned object is a
948 * key that can be used to unregister this factory.
949 * @param factory the factory to register
950 * @return a key with which to unregister the factory
953 public static Object registerFactory(NumberFormatFactory factory) {
954 if (factory == null) {
955 throw new IllegalArgumentException("factory must not be null");
957 return getShim().registerFactory(factory);
961 * {@icu} Unregisters the factory or instance associated with this key (obtained from
962 * registerInstance or registerFactory).
963 * @param registryKey a key obtained from registerFactory
964 * @return true if the object was successfully unregistered
967 public static boolean unregister(Object registryKey) {
968 if (registryKey == null) {
969 throw new IllegalArgumentException("registryKey must not be null");
976 return shim.unregister(registryKey);
979 // ===== End of factory stuff =====
982 * Overrides hashCode.
986 public int hashCode() {
987 return maximumIntegerDigits * 37 + maxFractionDigits;
988 // just enough fields for a reasonable distribution
993 * Two NumberFormats are equal if they are of the same class
994 * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
996 * @param obj the object to compare against
997 * @return true if the object is equal to this.
1001 public boolean equals(Object obj) {
1002 if (obj == null) return false;
1005 if (getClass() != obj.getClass())
1007 NumberFormat other = (NumberFormat) obj;
1008 return maximumIntegerDigits == other.maximumIntegerDigits
1009 && minimumIntegerDigits == other.minimumIntegerDigits
1010 && maximumFractionDigits == other.maximumFractionDigits
1011 && minimumFractionDigits == other.minimumFractionDigits
1012 && groupingUsed == other.groupingUsed
1013 && parseIntegerOnly == other.parseIntegerOnly
1014 && parseStrict == other.parseStrict;
1022 public Object clone() {
1023 NumberFormat other = (NumberFormat) super.clone();
1028 * Returns true if grouping is used in this format. For example, in the
1029 * en_US locale, with grouping on, the number 1234567 will be formatted
1030 * as "1,234,567". The grouping separator as well as the size of each group
1031 * is locale-dependent and is determined by subclasses of NumberFormat.
1032 * Grouping affects both parsing and formatting.
1033 * @return true if grouping is used
1034 * @see #setGroupingUsed
1037 public boolean isGroupingUsed() {
1038 return groupingUsed;
1042 * Sets whether or not grouping will be used in this format. Grouping
1043 * affects both parsing and formatting.
1044 * @see #isGroupingUsed
1045 * @param newValue true to use grouping.
1048 public void setGroupingUsed(boolean newValue) {
1049 groupingUsed = newValue;
1053 * Returns the maximum number of digits allowed in the integer portion of a
1054 * number. The default value is 40, which subclasses can override.
1055 * When formatting, the exact behavior when this value is exceeded is
1056 * subclass-specific. When parsing, this has no effect.
1057 * @return the maximum number of integer digits
1058 * @see #setMaximumIntegerDigits
1061 public int getMaximumIntegerDigits() {
1062 return maximumIntegerDigits;
1066 * Sets the maximum number of digits allowed in the integer portion of a
1067 * number. This must be >= minimumIntegerDigits. If the
1068 * new value for maximumIntegerDigits is less than the current value
1069 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
1071 * @param newValue the maximum number of integer digits to be shown; if
1072 * less than zero, then zero is used. Subclasses might enforce an
1073 * upper limit to this value appropriate to the numeric type being formatted.
1074 * @see #getMaximumIntegerDigits
1077 public void setMaximumIntegerDigits(int newValue) {
1078 maximumIntegerDigits = Math.max(0,newValue);
1079 if (minimumIntegerDigits > maximumIntegerDigits)
1080 minimumIntegerDigits = maximumIntegerDigits;
1084 * Returns the minimum number of digits allowed in the integer portion of a
1085 * number. The default value is 1, which subclasses can override.
1086 * When formatting, if this value is not reached, numbers are padded on the
1087 * left with the locale-specific '0' character to ensure at least this
1088 * number of integer digits. When parsing, this has no effect.
1089 * @return the minimum number of integer digits
1090 * @see #setMinimumIntegerDigits
1093 public int getMinimumIntegerDigits() {
1094 return minimumIntegerDigits;
1098 * Sets the minimum number of digits allowed in the integer portion of a
1099 * number. This must be <= maximumIntegerDigits. If the
1100 * new value for minimumIntegerDigits is more than the current value
1101 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
1103 * @param newValue the minimum number of integer digits to be shown; if
1104 * less than zero, then zero is used. Subclasses might enforce an
1105 * upper limit to this value appropriate to the numeric type being formatted.
1106 * @see #getMinimumIntegerDigits
1109 public void setMinimumIntegerDigits(int newValue) {
1110 minimumIntegerDigits = Math.max(0,newValue);
1111 if (minimumIntegerDigits > maximumIntegerDigits)
1112 maximumIntegerDigits = minimumIntegerDigits;
1116 * Returns the maximum number of digits allowed in the fraction
1117 * portion of a number. The default value is 3, which subclasses
1118 * can override. When formatting, the exact behavior when this
1119 * value is exceeded is subclass-specific. When parsing, this has
1121 * @return the maximum number of fraction digits
1122 * @see #setMaximumFractionDigits
1125 public int getMaximumFractionDigits() {
1126 return maximumFractionDigits;
1130 * Sets the maximum number of digits allowed in the fraction portion of a
1131 * number. This must be >= minimumFractionDigits. If the
1132 * new value for maximumFractionDigits is less than the current value
1133 * of minimumFractionDigits, then minimumFractionDigits will also be set to
1135 * @param newValue the maximum number of fraction digits to be shown; if
1136 * less than zero, then zero is used. The concrete subclass may enforce an
1137 * upper limit to this value appropriate to the numeric type being formatted.
1138 * @see #getMaximumFractionDigits
1141 public void setMaximumFractionDigits(int newValue) {
1142 maximumFractionDigits = Math.max(0,newValue);
1143 if (maximumFractionDigits < minimumFractionDigits)
1144 minimumFractionDigits = maximumFractionDigits;
1148 * Returns the minimum number of digits allowed in the fraction portion of a
1149 * number. The default value is 0, which subclasses can override.
1150 * When formatting, if this value is not reached, numbers are padded on
1151 * the right with the locale-specific '0' character to ensure at least
1152 * this number of fraction digits. When parsing, this has no effect.
1153 * @return the minimum number of fraction digits
1154 * @see #setMinimumFractionDigits
1157 public int getMinimumFractionDigits() {
1158 return minimumFractionDigits;
1162 * Sets the minimum number of digits allowed in the fraction portion of a
1163 * number. This must be <= maximumFractionDigits. If the
1164 * new value for minimumFractionDigits exceeds the current value
1165 * of maximumFractionDigits, then maximumFractionDigits will also be set to
1167 * @param newValue the minimum number of fraction digits to be shown; if
1168 * less than zero, then zero is used. Subclasses might enforce an
1169 * upper limit to this value appropriate to the numeric type being formatted.
1170 * @see #getMinimumFractionDigits
1173 public void setMinimumFractionDigits(int newValue) {
1174 minimumFractionDigits = Math.max(0,newValue);
1175 if (maximumFractionDigits < minimumFractionDigits)
1176 maximumFractionDigits = minimumFractionDigits;
1180 * Sets the <tt>Currency</tt> object used to display currency
1181 * amounts. This takes effect immediately, if this format is a
1182 * currency format. If this format is not a currency format, then
1183 * the currency object is used if and when this object becomes a
1185 * @param theCurrency new currency object to use. May be null for
1189 public void setCurrency(Currency theCurrency) {
1190 currency = theCurrency;
1194 * Returns the <tt>Currency</tt> object used to display currency
1195 * amounts. This may be null.
1198 public Currency getCurrency() {
1203 * Returns the currency in effect for this formatter. Subclasses
1204 * should override this method as needed. Unlike getCurrency(),
1205 * this method should never return null.
1206 * @return a non-null Currency
1208 * @deprecated This API is ICU internal only.
1211 protected Currency getEffectiveCurrency() {
1212 Currency c = getCurrency();
1214 ULocale uloc = getLocale(ULocale.VALID_LOCALE);
1216 uloc = ULocale.getDefault(Category.FORMAT);
1218 c = Currency.getInstance(uloc);
1224 * Returns the rounding mode used in this NumberFormat. The default implementation of
1225 * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
1226 * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
1227 * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
1228 * @see #setRoundingMode(int)
1231 public int getRoundingMode() {
1232 throw new UnsupportedOperationException(
1233 "getRoundingMode must be implemented by the subclass implementation.");
1237 * Set the rounding mode used in this NumberFormat. The default implementation of
1238 * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
1239 * @param roundingMode A rounding mode, between
1240 * <code>BigDecimal.ROUND_UP</code> and
1241 * <code>BigDecimal.ROUND_UNNECESSARY</code>.
1242 * @see #getRoundingMode()
1245 public void setRoundingMode(int roundingMode) {
1246 throw new UnsupportedOperationException(
1247 "setRoundingMode must be implemented by the subclass implementation.");
1252 * Returns a specific style number format for a specific locale.
1253 * @param desiredLocale the specific locale.
1254 * @param choice number format style
1255 * @throws IllegalArgumentException if choice is not one of
1256 * NUMBERSTYLE, CURRENCYSTYLE,
1257 * PERCENTSTYLE, SCIENTIFICSTYLE,
1259 * ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,
1262 public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
1263 if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE) {
1264 throw new IllegalArgumentException(
1265 "choice should be from NUMBERSTYLE to PLURALCURRENCYSTYLE");
1267 // if (shim == null) {
1268 // return createInstance(desiredLocale, choice);
1270 // // TODO: shims must call setLocale() on object they create
1271 // return getShim().createInstance(desiredLocale, choice);
1273 return getShim().createInstance(desiredLocale, choice);
1276 // =======================privates===============================
1278 static NumberFormat createInstance(ULocale desiredLocale, int choice) {
1279 // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single
1280 // pattern, it is a pattern set, so we do not need to get them here.
1281 // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency
1282 // pattern in the locale but by replacing the single currency sign
1283 // with double currency sign.
1284 String pattern = getPattern(desiredLocale, choice);
1285 DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
1287 // Here we assume that the locale passed in is in the canonical
1288 // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
1289 // This style wont work for currency plural format.
1290 // For currency plural format, the pattern is get from
1291 // the locale (from CurrencyUnitPatterns) without override.
1292 if(choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE){
1293 String temp = symbols.getCurrencyPattern();
1299 // replace single currency sign in the pattern with double currency sign
1300 // if the choice is ISOCURRENCYSTYLE.
1301 if (choice == ISOCURRENCYSTYLE) {
1302 pattern = pattern.replace("\u00A4", doubleCurrencyStr);
1305 // Get the numbering system
1306 NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);
1311 NumberFormat format;
1313 if ( ns != null && ns.isAlgorithmic()) {
1315 String nsRuleSetGroup;
1316 String nsRuleSetName;
1318 int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;
1320 nsDesc = ns.getDescription();
1321 int firstSlash = nsDesc.indexOf("/");
1322 int lastSlash = nsDesc.lastIndexOf("/");
1324 if ( lastSlash > firstSlash ) {
1325 String nsLocID = nsDesc.substring(0,firstSlash);
1326 nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);
1327 nsRuleSetName = nsDesc.substring(lastSlash+1);
1329 nsLoc = new ULocale(nsLocID);
1330 if ( nsRuleSetGroup.equals("SpelloutRules")) {
1331 desiredRulesType = RuleBasedNumberFormat.SPELLOUT;
1334 nsLoc = desiredLocale;
1335 nsRuleSetName = nsDesc;
1338 RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);
1339 r.setDefaultRuleSet(nsRuleSetName);
1342 DecimalFormat f = new DecimalFormat(pattern, symbols, choice);
1343 // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
1346 Add codes for the new method getIntegerInstance() [Richard/GCL]
1348 // TODO: revisit this -- this is almost certainly not the way we want
1349 // to do this. aliu 1/6/2004
1350 if (choice == INTEGERSTYLE) {
1351 f.setMaximumFractionDigits(0);
1352 f.setDecimalSeparatorAlwaysShown(false);
1353 f.setParseIntegerOnly(true);
1357 // TODO: the actual locale of the *pattern* may differ from that
1358 // for the *symbols*. For now, we use the data for the symbols.
1360 ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
1361 ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
1362 format.setLocale(valid, actual);
1368 * Returns the pattern for the provided locale and choice.
1369 * @param forLocale the locale of the data.
1370 * @param choice the pattern format.
1371 * @return the pattern
1372 * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
1375 protected static String getPattern(Locale forLocale, int choice) {
1376 return getPattern(ULocale.forLocale(forLocale), choice);
1380 * Returns the pattern for the provided locale and choice.
1381 * @param forLocale the locale of the data.
1382 * @param choice the pattern format.
1383 * @return the pattern
1386 protected static String getPattern(ULocale forLocale, int choice) {
1388 /* The following code takes care of a few cases where the
1389 * resource data in the underlying JDK lags the new features
1390 * we have added to ICU4J: scientific notation, rounding, and
1391 * secondary grouping.
1393 * We detect these cases here and return various hard-coded
1394 * resource data. This is the simplest solution for now, but
1395 * it is not a good long-term mechanism.
1397 * We should replace this code with a data-driven mechanism
1398 * that reads the bundle com.ibm.icu.impl.data.LocaleElements
1399 * and parses an exception table that overrides the standard
1400 * data at java.text.resource.LocaleElements*.java.
1401 * Alternatively, we should create our own copy of the
1402 * resource data, and use that exclusively.
1405 // TEMPORARY, until we get scientific patterns into the main
1406 // resources: Retrieve scientific patterns from our resources.
1407 //if (choice == SCIENTIFICSTYLE) {
1408 // Temporarily hard code; retrieve from resource later
1409 /*For ICU compatibility [Richard/GCL]*/
1411 // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];
1415 // Try the cache first
1416 String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);
1417 if (numberPatterns == null) {
1418 OverlayBundle resource = new OverlayBundle(new String[]
1419 { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);
1420 numberPatterns = resource.getStringArray("NumberPatterns");
1422 cachedLocaleData.put(forLocale, numberPatterns);
1426 /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,
1427 * the pattern is the same as the pattern of CURRENCYSTYLE
1428 * but by replacing the single currency sign with
1429 * double currency sign or triple currency sign.
1431 int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE :
1432 ((choice == ISOCURRENCYSTYLE || choice == PLURALCURRENCYSTYLE)?
1433 CURRENCYSTYLE : choice); //[Richard/GCL]
1435 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
1436 getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
1437 String[] numberPatternKeys = { "decimalFormat", "currencyFormat", "percentFormat", "scientificFormat" };
1438 NumberingSystem ns = NumberingSystem.getInstance(forLocale);
1440 String result = null;
1442 result = rb.getStringWithFallback("NumberElements/" + ns.getName() + "/patterns/"+numberPatternKeys[entry]);
1443 } catch ( MissingResourceException ex ) {
1444 result = rb.getStringWithFallback("NumberElements/latn/patterns/"+numberPatternKeys[entry]);
1451 * First, read in the default serializable data.
1453 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
1454 * the stream was written by JDK 1.1,
1455 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1456 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
1457 * since the <code>int</code> fields were not present in JDK 1.1.
1458 * Finally, set serialVersionOnStream back to the maximum allowed value so that
1459 * default serialization will work properly if this object is streamed out again.
1461 private void readObject(ObjectInputStream stream)
1462 throws IOException, ClassNotFoundException
1464 stream.defaultReadObject();
1466 // we don't have serialization data for this format
1467 if (serialVersionOnStream < 1) {
1468 // Didn't have additional int fields, reassign to use them.
1469 maximumIntegerDigits = maxIntegerDigits;
1470 minimumIntegerDigits = minIntegerDigits;
1471 maximumFractionDigits = maxFractionDigits;
1472 minimumFractionDigits = minFractionDigits;
1476 Validate the min and max fields [Richard/GCL]
1478 if (minimumIntegerDigits > maximumIntegerDigits ||
1479 minimumFractionDigits > maximumFractionDigits ||
1480 minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
1481 throw new InvalidObjectException("Digit count range invalid");
1483 serialVersionOnStream = currentSerialVersion;
1487 * Write out the default serializable data, after first setting
1488 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
1489 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1490 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
1491 * with the JDK 1.1 version of the stream format.
1493 private void writeObject(ObjectOutputStream stream)
1496 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1497 (byte)maximumIntegerDigits;
1498 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1499 (byte)minimumIntegerDigits;
1500 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1501 (byte)maximumFractionDigits;
1502 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1503 (byte)minimumFractionDigits;
1504 stream.defaultWriteObject();
1507 // Unused -- Alan 2003-05
1509 // * Cache to hold the NumberPatterns of a Locale.
1511 // private static final Hashtable cachedLocaleData = new Hashtable(3);
1513 private static final char[] doubleCurrencySign = {0xA4, 0xA4};
1514 private static final String doubleCurrencyStr = new String(doubleCurrencySign);
1517 Add Field for the new method getIntegerInstance() [Richard/GCL]
1522 * True if the the grouping (i.e. thousands) separator is used when
1523 * formatting and parsing numbers.
1526 * @see #isGroupingUsed
1528 private boolean groupingUsed = true;
1531 * The maximum number of digits allowed in the integer portion of a
1532 * number. <code>maxIntegerDigits</code> must be greater than or equal to
1533 * <code>minIntegerDigits</code>.
1535 * <strong>Note:</strong> This field exists only for serialization
1536 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1537 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
1538 * When writing to a stream, <code>maxIntegerDigits</code> is set to
1539 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1540 * whichever is smaller. When reading from a stream, this field is used
1541 * only if <code>serialVersionOnStream</code> is less than 1.
1544 * @see #getMaximumIntegerDigits
1546 private byte maxIntegerDigits = 40;
1549 * The minimum number of digits allowed in the integer portion of a
1550 * number. <code>minimumIntegerDigits</code> must be less than or equal to
1551 * <code>maximumIntegerDigits</code>.
1553 * <strong>Note:</strong> This field exists only for serialization
1554 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1555 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
1556 * When writing to a stream, <code>minIntegerDigits</code> is set to
1557 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1558 * whichever is smaller. When reading from a stream, this field is used
1559 * only if <code>serialVersionOnStream</code> is less than 1.
1562 * @see #getMinimumIntegerDigits
1564 private byte minIntegerDigits = 1;
1567 * The maximum number of digits allowed in the fractional portion of a
1568 * number. <code>maximumFractionDigits</code> must be greater than or equal to
1569 * <code>minimumFractionDigits</code>.
1571 * <strong>Note:</strong> This field exists only for serialization
1572 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1573 * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
1574 * When writing to a stream, <code>maxFractionDigits</code> is set to
1575 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1576 * whichever is smaller. When reading from a stream, this field is used
1577 * only if <code>serialVersionOnStream</code> is less than 1.
1580 * @see #getMaximumFractionDigits
1582 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
1585 * The minimum number of digits allowed in the fractional portion of a
1586 * number. <code>minimumFractionDigits</code> must be less than or equal to
1587 * <code>maximumFractionDigits</code>.
1589 * <strong>Note:</strong> This field exists only for serialization
1590 * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
1591 * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
1592 * When writing to a stream, <code>minFractionDigits</code> is set to
1593 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1594 * whichever is smaller. When reading from a stream, this field is used
1595 * only if <code>serialVersionOnStream</code> is less than 1.
1598 * @see #getMinimumFractionDigits
1600 private byte minFractionDigits = 0;
1603 * True if this format will parse numbers as integers only.
1606 * @see #isParseIntegerOnly
1608 private boolean parseIntegerOnly = false;
1610 // new fields for 1.2. byte is too small for integer digits.
1613 * The maximum number of digits allowed in the integer portion of a
1614 * number. <code>maximumIntegerDigits</code> must be greater than or equal to
1615 * <code>minimumIntegerDigits</code>.
1618 * @see #getMaximumIntegerDigits
1620 private int maximumIntegerDigits = 40;
1623 * The minimum number of digits allowed in the integer portion of a
1624 * number. <code>minimumIntegerDigits</code> must be less than or equal to
1625 * <code>maximumIntegerDigits</code>.
1628 * @see #getMinimumIntegerDigits
1630 private int minimumIntegerDigits = 1;
1633 * The maximum number of digits allowed in the fractional portion of a
1634 * number. <code>maximumFractionDigits</code> must be greater than or equal to
1635 * <code>minimumFractionDigits</code>.
1638 * @see #getMaximumFractionDigits
1640 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
1643 * The minimum number of digits allowed in the fractional portion of a
1644 * number. <code>minimumFractionDigits</code> must be less than or equal to
1645 * <code>maximumFractionDigits</code>.
1648 * @see #getMinimumFractionDigits
1650 private int minimumFractionDigits = 0;
1653 * Currency object used to format currencies. Subclasses may
1654 * ignore this if they are not currency formats. This will be
1655 * null unless a subclass sets it to a non-null value.
1658 private Currency currency;
1660 static final int currentSerialVersion = 1;
1663 * Describes the version of <code>NumberFormat</code> present on the stream.
1664 * Possible values are:
1666 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
1667 * In this version, the <code>int</code> fields such as
1668 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
1669 * fields such as <code>maxIntegerDigits</code> are used instead.
1671 * <li><b>1</b>: the JDK 1.2 version of the stream format. The values of the
1672 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
1673 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1676 * When streaming out a <code>NumberFormat</code>, the most recent format
1677 * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
1678 * is always written.
1682 private int serialVersionOnStream = currentSerialVersion;
1684 // Removed "implements Cloneable" clause. Needs to update serialization
1685 // ID for backward compatibility.
1686 private static final long serialVersionUID = -2308460125733713944L;
1689 * Empty constructor. Public for compatibily with JDK which lets the
1690 * compiler generate a default public constructor even though this is
1691 * an abstract class.
1694 public NumberFormat() {
1698 private boolean parseStrict;
1701 * The instances of this inner class are used as attribute keys and values
1702 * in AttributedCharacterIterator that
1703 * NumberFormat.formatToCharacterIterator() method returns.
1705 * There is no public constructor to this class, the only instances are the
1706 * constants defined here.
1710 public static class Field extends Format.Field {
1711 // generated by serialver from JDK 1.4.1_01
1712 static final long serialVersionUID = -4516273749929385842L;
1717 public static final Field SIGN = new Field("sign");
1722 public static final Field INTEGER = new Field("integer");
1727 public static final Field FRACTION = new Field("fraction");
1732 public static final Field EXPONENT = new Field("exponent");
1737 public static final Field EXPONENT_SIGN = new Field("exponent sign");
1742 public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
1747 public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
1751 public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
1756 public static final Field PERCENT = new Field("percent");
1761 public static final Field PERMILLE = new Field("per mille");
1766 public static final Field CURRENCY = new Field("currency");
1769 * Constructs a new instance of NumberFormat.Field with the given field
1773 protected Field(String fieldName) {
1778 * serizalization method resolve instances to the constant
1779 * NumberFormat.Field values
1783 protected Object readResolve() throws InvalidObjectException {
1784 if (this.getName().equals(INTEGER.getName()))
1786 if (this.getName().equals(FRACTION.getName()))
1788 if (this.getName().equals(EXPONENT.getName()))
1790 if (this.getName().equals(EXPONENT_SIGN.getName()))
1791 return EXPONENT_SIGN;
1792 if (this.getName().equals(EXPONENT_SYMBOL.getName()))
1793 return EXPONENT_SYMBOL;
1794 if (this.getName().equals(CURRENCY.getName()))
1796 if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
1797 return DECIMAL_SEPARATOR;
1798 if (this.getName().equals(GROUPING_SEPARATOR.getName()))
1799 return GROUPING_SEPARATOR;
1800 if (this.getName().equals(PERCENT.getName()))
1802 if (this.getName().equals(PERMILLE.getName()))
1804 if (this.getName().equals(SIGN.getName()))
1807 throw new InvalidObjectException("An invalid object.");