1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 /* 28 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 29 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 30 * 31 * The original version of this source code and documentation is copyrighted 32 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These 33 * materials are provided under terms of a License Agreement between Taligent 34 * and Sun. This technology is protected by multiple US and International 35 * patents. This notice and attribution to Taligent may not be removed. 36 * Taligent is a registered trademark of Taligent, Inc. 37 * 38 */ 39 40 package java.text; 41 42 import java.io.InvalidObjectException; 43 import java.io.IOException; 44 import java.io.ObjectInputStream; 45 import java.io.ObjectOutputStream; 46 import java.math.BigInteger; 47 import java.math.RoundingMode; 48 import java.util.Currency; 49 import java.util.HashMap; 50 import java.util.Hashtable; 51 import java.util.Locale; 52 import java.util.Map; 53 import java.util.concurrent.atomic.AtomicInteger; 54 import java.util.concurrent.atomic.AtomicLong; 55 import libcore.icu.ICU; 56 import libcore.icu.LocaleData; 57 58 /** 59 * <code>NumberFormat</code> is the abstract base class for all number 60 * formats. This class provides the interface for formatting and parsing 61 * numbers. <code>NumberFormat</code> also provides methods for determining 62 * which locales have number formats, and what their names are. 63 * 64 * <p> 65 * <code>NumberFormat</code> helps you to format and parse numbers for any locale. 66 * Your code can be completely independent of the locale conventions for 67 * decimal points, thousands-separators, or even the particular decimal 68 * digits used, or whether the number format is even decimal. 69 * 70 * <p> 71 * To format a number for the current Locale, use one of the factory 72 * class methods: 73 * <blockquote> 74 * <pre>{@code 75 * myString = NumberFormat.getInstance().format(myNumber); 76 * }</pre> 77 * </blockquote> 78 * If you are formatting multiple numbers, it is 79 * more efficient to get the format and use it multiple times so that 80 * the system doesn't have to fetch the information about the local 81 * language and country conventions multiple times. 82 * <blockquote> 83 * <pre>{@code 84 * NumberFormat nf = NumberFormat.getInstance(); 85 * for (int i = 0; i < myNumber.length; ++i) { 86 * output.println(nf.format(myNumber[i]) + "; "); 87 * } 88 * }</pre> 89 * </blockquote> 90 * To format a number for a different Locale, specify it in the 91 * call to <code>getInstance</code>. 92 * <blockquote> 93 * <pre>{@code 94 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH); 95 * }</pre> 96 * </blockquote> 97 * You can also use a <code>NumberFormat</code> to parse numbers: 98 * <blockquote> 99 * <pre>{@code 100 * myNumber = nf.parse(myString); 101 * }</pre> 102 * </blockquote> 103 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the 104 * normal number format. Use <code>getIntegerInstance</code> to get an 105 * integer number format. Use <code>getCurrencyInstance</code> to get the 106 * currency number format. And use <code>getPercentInstance</code> to get a 107 * format for displaying percentages. With this format, a fraction like 108 * 0.53 is displayed as 53%. 109 * 110 * <p> 111 * You can also control the display of numbers with such methods as 112 * <code>setMinimumFractionDigits</code>. 113 * If you want even more control over the format or parsing, 114 * or want to give your users more control, 115 * you can try casting the <code>NumberFormat</code> you get from the factory methods 116 * to a <code>DecimalFormat</code>. This will work for the vast majority 117 * of locales; just remember to put it in a <code>try</code> block in case you 118 * encounter an unusual one. 119 * 120 * <p> 121 * NumberFormat and DecimalFormat are designed such that some controls 122 * work for formatting and others work for parsing. The following is 123 * the detailed description for each these control methods, 124 * <p> 125 * setParseIntegerOnly : only affects parsing, e.g. 126 * if true, "3456.78" → 3456 (and leaves the parse position just after index 6) 127 * if false, "3456.78" → 3456.78 (and leaves the parse position just after index 8) 128 * This is independent of formatting. If you want to not show a decimal point 129 * where there might be no digits after the decimal point, use 130 * setDecimalSeparatorAlwaysShown. 131 * <p> 132 * setDecimalSeparatorAlwaysShown : only affects formatting, and only where 133 * there might be no digits after the decimal point, such as with a pattern 134 * like "#,##0.##", e.g., 135 * if true, 3456.00 → "3,456." 136 * if false, 3456.00 → "3456" 137 * This is independent of parsing. If you want parsing to stop at the decimal 138 * point, use setParseIntegerOnly. 139 * 140 * <p> 141 * You can also use forms of the <code>parse</code> and <code>format</code> 142 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to 143 * allow you to: 144 * <ul> 145 * <li> progressively parse through pieces of a string 146 * <li> align the decimal point and other areas 147 * </ul> 148 * For example, you can align numbers in two ways: 149 * <ol> 150 * <li> If you are using a monospaced font with spacing for alignment, 151 * you can pass the <code>FieldPosition</code> in your format call, with 152 * <code>field</code> = <code>INTEGER_FIELD</code>. On output, 153 * <code>getEndIndex</code> will be set to the offset between the 154 * last character of the integer and the decimal. Add 155 * (desiredSpaceCount - getEndIndex) spaces at the front of the string. 156 * 157 * <li> If you are using proportional fonts, 158 * instead of padding with spaces, measure the width 159 * of the string in pixels from the start to <code>getEndIndex</code>. 160 * Then move the pen by 161 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text. 162 * It also works where there is no decimal, but possibly additional 163 * characters at the end, e.g., with parentheses in negative 164 * numbers: "(12)" for -12. 165 * </ol> 166 * 167 * <h3><a name="synchronization">Synchronization</a></h3> 168 * 169 * <p> 170 * Number formats are generally not synchronized. 171 * It is recommended to create separate format instances for each thread. 172 * If multiple threads access a format concurrently, it must be synchronized 173 * externally. 174 * 175 * @see DecimalFormat 176 * @see ChoiceFormat 177 * @author Mark Davis 178 * @author Helena Shih 179 */ 180 public abstract class NumberFormat extends Format { 181 182 /** 183 * Field constant used to construct a FieldPosition object. Signifies that 184 * the position of the integer part of a formatted number should be returned. 185 * @see java.text.FieldPosition 186 */ 187 public static final int INTEGER_FIELD = 0; 188 189 /** 190 * Field constant used to construct a FieldPosition object. Signifies that 191 * the position of the fraction part of a formatted number should be returned. 192 * @see java.text.FieldPosition 193 */ 194 public static final int FRACTION_FIELD = 1; 195 196 /** 197 * Sole constructor. (For invocation by subclass constructors, typically 198 * implicit.) 199 */ NumberFormat()200 protected NumberFormat() { 201 } 202 203 /** 204 * Formats a number and appends the resulting text to the given string 205 * buffer. 206 * The number can be of any subclass of {@link java.lang.Number}. 207 * <p> 208 * This implementation extracts the number's value using 209 * {@link java.lang.Number#longValue()} for all integral type values that 210 * can be converted to <code>long</code> without loss of information, 211 * including <code>BigInteger</code> values with a 212 * {@link java.math.BigInteger#bitLength() bit length} of less than 64, 213 * and {@link java.lang.Number#doubleValue()} for all other types. It 214 * then calls 215 * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)} 216 * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}. 217 * This may result in loss of magnitude information and precision for 218 * <code>BigInteger</code> and <code>BigDecimal</code> values. 219 * @param number the number to format 220 * @param toAppendTo the <code>StringBuffer</code> to which the formatted 221 * text is to be appended 222 * @param pos On input: an alignment field, if desired. 223 * On output: the offsets of the alignment field. 224 * @return the value passed in as <code>toAppendTo</code> 225 * @exception IllegalArgumentException if <code>number</code> is 226 * null or not an instance of <code>Number</code>. 227 * @exception NullPointerException if <code>toAppendTo</code> or 228 * <code>pos</code> is null 229 * @exception ArithmeticException if rounding is needed with rounding 230 * mode being set to RoundingMode.UNNECESSARY 231 * @see java.text.FieldPosition 232 */ 233 @Override format(Object number, StringBuffer toAppendTo, FieldPosition pos)234 public StringBuffer format(Object number, 235 StringBuffer toAppendTo, 236 FieldPosition pos) { 237 if (number instanceof Long || number instanceof Integer || 238 number instanceof Short || number instanceof Byte || 239 number instanceof AtomicInteger || number instanceof AtomicLong || 240 (number instanceof BigInteger && 241 ((BigInteger)number).bitLength() < 64)) { 242 return format(((Number)number).longValue(), toAppendTo, pos); 243 } else if (number instanceof Number) { 244 return format(((Number)number).doubleValue(), toAppendTo, pos); 245 } else { 246 throw new IllegalArgumentException("Cannot format given Object as a Number"); 247 } 248 } 249 250 /** 251 * Parses text from a string to produce a <code>Number</code>. 252 * <p> 253 * The method attempts to parse text starting at the index given by 254 * <code>pos</code>. 255 * If parsing succeeds, then the index of <code>pos</code> is updated 256 * to the index after the last character used (parsing does not necessarily 257 * use all characters up to the end of the string), and the parsed 258 * number is returned. The updated <code>pos</code> can be used to 259 * indicate the starting point for the next call to this method. 260 * If an error occurs, then the index of <code>pos</code> is not 261 * changed, the error index of <code>pos</code> is set to the index of 262 * the character where the error occurred, and null is returned. 263 * <p> 264 * See the {@link #parse(String, ParsePosition)} method for more information 265 * on number parsing. 266 * 267 * @param source A <code>String</code>, part of which should be parsed. 268 * @param pos A <code>ParsePosition</code> object with index and error 269 * index information as described above. 270 * @return A <code>Number</code> parsed from the string. In case of 271 * error, returns null. 272 * @exception NullPointerException if <code>pos</code> is null. 273 */ 274 @Override parseObject(String source, ParsePosition pos)275 public final Object parseObject(String source, ParsePosition pos) { 276 return parse(source, pos); 277 } 278 279 /** 280 * Specialization of format. 281 * 282 * @param number the double number to format 283 * @return the formatted String 284 * @exception ArithmeticException if rounding is needed with rounding 285 * mode being set to RoundingMode.UNNECESSARY 286 * @see java.text.Format#format 287 */ format(double number)288 public final String format(double number) { 289 return format(number, new StringBuffer(), 290 DontCareFieldPosition.INSTANCE).toString(); 291 } 292 293 /** 294 * Specialization of format. 295 * 296 * @param number the long number to format 297 * @return the formatted String 298 * @exception ArithmeticException if rounding is needed with rounding 299 * mode being set to RoundingMode.UNNECESSARY 300 * @see java.text.Format#format 301 */ format(long number)302 public final String format(long number) { 303 return format(number, new StringBuffer(), 304 DontCareFieldPosition.INSTANCE).toString(); 305 } 306 307 /** 308 * Specialization of format. 309 * 310 * @param number the double number to format 311 * @param toAppendTo the StringBuffer to which the formatted text is to be 312 * appended 313 * @param pos the field position 314 * @return the formatted StringBuffer 315 * @exception ArithmeticException if rounding is needed with rounding 316 * mode being set to RoundingMode.UNNECESSARY 317 * @see java.text.Format#format 318 */ format(double number, StringBuffer toAppendTo, FieldPosition pos)319 public abstract StringBuffer format(double number, 320 StringBuffer toAppendTo, 321 FieldPosition pos); 322 323 /** 324 * Specialization of format. 325 * 326 * @param number the long number to format 327 * @param toAppendTo the StringBuffer to which the formatted text is to be 328 * appended 329 * @param pos the field position 330 * @return the formatted StringBuffer 331 * @exception ArithmeticException if rounding is needed with rounding 332 * mode being set to RoundingMode.UNNECESSARY 333 * @see java.text.Format#format 334 */ format(long number, StringBuffer toAppendTo, FieldPosition pos)335 public abstract StringBuffer format(long number, 336 StringBuffer toAppendTo, 337 FieldPosition pos); 338 339 /** 340 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, 341 * Long.MAX_VALUE] and with no decimals), otherwise a Double. 342 * If IntegerOnly is set, will stop at a decimal 343 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop 344 * after the 1). 345 * Does not throw an exception; if no object can be parsed, index is 346 * unchanged! 347 * 348 * @param source the String to parse 349 * @param parsePosition the parse position 350 * @return the parsed value 351 * @see java.text.NumberFormat#isParseIntegerOnly 352 * @see java.text.Format#parseObject 353 */ parse(String source, ParsePosition parsePosition)354 public abstract Number parse(String source, ParsePosition parsePosition); 355 356 /** 357 * Parses text from the beginning of the given string to produce a number. 358 * The method may not use the entire text of the given string. 359 * <p> 360 * See the {@link #parse(String, ParsePosition)} method for more information 361 * on number parsing. 362 * 363 * @param source A <code>String</code> whose beginning should be parsed. 364 * @return A <code>Number</code> parsed from the string. 365 * @exception ParseException if the beginning of the specified string 366 * cannot be parsed. 367 */ parse(String source)368 public Number parse(String source) throws ParseException { 369 ParsePosition parsePosition = new ParsePosition(0); 370 Number result = parse(source, parsePosition); 371 if (parsePosition.index == 0) { 372 throw new ParseException("Unparseable number: \"" + source + "\"", 373 parsePosition.errorIndex); 374 } 375 return result; 376 } 377 378 /** 379 * Returns true if this format will parse numbers as integers only. 380 * For example in the English locale, with ParseIntegerOnly true, the 381 * string "1234." would be parsed as the integer value 1234 and parsing 382 * would stop at the "." character. Of course, the exact format accepted 383 * by the parse operation is locale dependant and determined by sub-classes 384 * of NumberFormat. 385 * 386 * @return {@code true} if numbers should be parsed as integers only; 387 * {@code false} otherwise 388 */ isParseIntegerOnly()389 public boolean isParseIntegerOnly() { 390 return parseIntegerOnly; 391 } 392 393 /** 394 * Sets whether or not numbers should be parsed as integers only. 395 * 396 * @param value {@code true} if numbers should be parsed as integers only; 397 * {@code false} otherwise 398 * @see #isParseIntegerOnly 399 */ setParseIntegerOnly(boolean value)400 public void setParseIntegerOnly(boolean value) { 401 parseIntegerOnly = value; 402 } 403 404 //============== Locale Stuff ===================== 405 406 /** 407 * Returns a general-purpose number format for the current default 408 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 409 * This is the same as calling 410 * {@link #getNumberInstance() getNumberInstance()}. 411 * 412 * @return the {@code NumberFormat} instance for general-purpose number 413 * formatting 414 */ getInstance()415 public final static NumberFormat getInstance() { 416 return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE); 417 } 418 419 /** 420 * Returns a general-purpose number format for the specified locale. 421 * This is the same as calling 422 * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}. 423 * 424 * @param inLocale the desired locale 425 * @return the {@code NumberFormat} instance for general-purpose number 426 * formatting 427 */ getInstance(Locale inLocale)428 public static NumberFormat getInstance(Locale inLocale) { 429 return getInstance(inLocale, NUMBERSTYLE); 430 } 431 432 /** 433 * Returns a general-purpose number format for the current default 434 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 435 * <p>This is equivalent to calling 436 * {@link #getNumberInstance(Locale) 437 * getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}. 438 * 439 * @return the {@code NumberFormat} instance for general-purpose number 440 * formatting 441 * @see java.util.Locale#getDefault(java.util.Locale.Category) 442 * @see java.util.Locale.Category#FORMAT 443 */ getNumberInstance()444 public final static NumberFormat getNumberInstance() { 445 return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE); 446 } 447 448 /** 449 * Returns a general-purpose number format for the specified locale. 450 * 451 * @param inLocale the desired locale 452 * @return the {@code NumberFormat} instance for general-purpose number 453 * formatting 454 */ getNumberInstance(Locale inLocale)455 public static NumberFormat getNumberInstance(Locale inLocale) { 456 return getInstance(inLocale, NUMBERSTYLE); 457 } 458 459 /** 460 * Returns an integer number format for the current default 461 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. The 462 * returned number format is configured to round floating point numbers 463 * to the nearest integer using half-even rounding (see {@link 464 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 465 * and to parse only the integer part of an input string (see {@link 466 * #isParseIntegerOnly isParseIntegerOnly}). 467 * <p>This is equivalent to calling 468 * {@link #getIntegerInstance(Locale) 469 * getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}. 470 * 471 * @see #getRoundingMode() 472 * @see java.util.Locale#getDefault(java.util.Locale.Category) 473 * @see java.util.Locale.Category#FORMAT 474 * @return a number format for integer values 475 * @since 1.4 476 */ getIntegerInstance()477 public final static NumberFormat getIntegerInstance() { 478 return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE); 479 } 480 481 /** 482 * Returns an integer number format for the specified locale. The 483 * returned number format is configured to round floating point numbers 484 * to the nearest integer using half-even rounding (see {@link 485 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 486 * and to parse only the integer part of an input string (see {@link 487 * #isParseIntegerOnly isParseIntegerOnly}). 488 * 489 * @param inLocale the desired locale 490 * @see #getRoundingMode() 491 * @return a number format for integer values 492 * @since 1.4 493 */ getIntegerInstance(Locale inLocale)494 public static NumberFormat getIntegerInstance(Locale inLocale) { 495 return getInstance(inLocale, INTEGERSTYLE); 496 } 497 498 /** 499 * Returns a currency format for the current default 500 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 501 * <p>This is equivalent to calling 502 * {@link #getCurrencyInstance(Locale) 503 * getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}. 504 * 505 * @return the {@code NumberFormat} instance for currency formatting 506 * @see java.util.Locale#getDefault(java.util.Locale.Category) 507 * @see java.util.Locale.Category#FORMAT 508 */ getCurrencyInstance()509 public final static NumberFormat getCurrencyInstance() { 510 return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE); 511 } 512 513 /** 514 * Returns a currency format for the specified locale. 515 * 516 * @param inLocale the desired locale 517 * @return the {@code NumberFormat} instance for currency formatting 518 */ getCurrencyInstance(Locale inLocale)519 public static NumberFormat getCurrencyInstance(Locale inLocale) { 520 return getInstance(inLocale, CURRENCYSTYLE); 521 } 522 523 /** 524 * Returns a percentage format for the current default 525 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 526 * <p>This is equivalent to calling 527 * {@link #getPercentInstance(Locale) 528 * getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}. 529 * 530 * @return the {@code NumberFormat} instance for percentage formatting 531 * @see java.util.Locale#getDefault(java.util.Locale.Category) 532 * @see java.util.Locale.Category#FORMAT 533 */ getPercentInstance()534 public final static NumberFormat getPercentInstance() { 535 return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE); 536 } 537 538 /** 539 * Returns a percentage format for the specified locale. 540 * 541 * @param inLocale the desired locale 542 * @return the {@code NumberFormat} instance for percentage formatting 543 */ getPercentInstance(Locale inLocale)544 public static NumberFormat getPercentInstance(Locale inLocale) { 545 return getInstance(inLocale, PERCENTSTYLE); 546 } 547 548 // Android-changed: Removed reference to NumberFormatProvider. 549 /** 550 * Returns an array of all locales for which the 551 * <code>get*Instance</code> methods of this class can return 552 * localized instances. 553 * 554 * @return An array of locales for which localized 555 * <code>NumberFormat</code> instances are available. 556 */ getAvailableLocales()557 public static Locale[] getAvailableLocales() { 558 // Android-changed: Removed used of NumberFormatProvider. Switched to use ICU. 559 return ICU.getAvailableLocales(); 560 } 561 562 /** 563 * Overrides hashCode. 564 */ 565 @Override hashCode()566 public int hashCode() { 567 return maximumIntegerDigits * 37 + maxFractionDigits; 568 // just enough fields for a reasonable distribution 569 } 570 571 /** 572 * Overrides equals. 573 */ 574 @Override equals(Object obj)575 public boolean equals(Object obj) { 576 if (obj == null) { 577 return false; 578 } 579 if (this == obj) { 580 return true; 581 } 582 if (getClass() != obj.getClass()) { 583 return false; 584 } 585 NumberFormat other = (NumberFormat) obj; 586 return (maximumIntegerDigits == other.maximumIntegerDigits 587 && minimumIntegerDigits == other.minimumIntegerDigits 588 && maximumFractionDigits == other.maximumFractionDigits 589 && minimumFractionDigits == other.minimumFractionDigits 590 && groupingUsed == other.groupingUsed 591 && parseIntegerOnly == other.parseIntegerOnly); 592 } 593 594 /** 595 * Overrides Cloneable. 596 */ 597 @Override clone()598 public Object clone() { 599 NumberFormat other = (NumberFormat) super.clone(); 600 return other; 601 } 602 603 /** 604 * Returns true if grouping is used in this format. For example, in the 605 * English locale, with grouping on, the number 1234567 might be formatted 606 * as "1,234,567". The grouping separator as well as the size of each group 607 * is locale dependant and is determined by sub-classes of NumberFormat. 608 * 609 * @return {@code true} if grouping is used; 610 * {@code false} otherwise 611 * @see #setGroupingUsed 612 */ isGroupingUsed()613 public boolean isGroupingUsed() { 614 return groupingUsed; 615 } 616 617 /** 618 * Set whether or not grouping will be used in this format. 619 * 620 * @param newValue {@code true} if grouping is used; 621 * {@code false} otherwise 622 * @see #isGroupingUsed 623 */ setGroupingUsed(boolean newValue)624 public void setGroupingUsed(boolean newValue) { 625 groupingUsed = newValue; 626 } 627 628 /** 629 * Returns the maximum number of digits allowed in the integer portion of a 630 * number. 631 * 632 * @return the maximum number of digits 633 * @see #setMaximumIntegerDigits 634 */ getMaximumIntegerDigits()635 public int getMaximumIntegerDigits() { 636 return maximumIntegerDigits; 637 } 638 639 /** 640 * Sets the maximum number of digits allowed in the integer portion of a 641 * number. maximumIntegerDigits must be ≥ minimumIntegerDigits. If the 642 * new value for maximumIntegerDigits is less than the current value 643 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to 644 * the new value. 645 * 646 * @param newValue the maximum number of integer digits to be shown; if 647 * less than zero, then zero is used. The concrete subclass may enforce an 648 * upper limit to this value appropriate to the numeric type being formatted. 649 * @see #getMaximumIntegerDigits 650 */ setMaximumIntegerDigits(int newValue)651 public void setMaximumIntegerDigits(int newValue) { 652 maximumIntegerDigits = Math.max(0,newValue); 653 if (minimumIntegerDigits > maximumIntegerDigits) { 654 minimumIntegerDigits = maximumIntegerDigits; 655 } 656 } 657 658 /** 659 * Returns the minimum number of digits allowed in the integer portion of a 660 * number. 661 * 662 * @return the minimum number of digits 663 * @see #setMinimumIntegerDigits 664 */ getMinimumIntegerDigits()665 public int getMinimumIntegerDigits() { 666 return minimumIntegerDigits; 667 } 668 669 /** 670 * Sets the minimum number of digits allowed in the integer portion of a 671 * number. minimumIntegerDigits must be ≤ maximumIntegerDigits. If the 672 * new value for minimumIntegerDigits exceeds the current value 673 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to 674 * the new value 675 * 676 * @param newValue the minimum number of integer digits to be shown; if 677 * less than zero, then zero is used. The concrete subclass may enforce an 678 * upper limit to this value appropriate to the numeric type being formatted. 679 * @see #getMinimumIntegerDigits 680 */ setMinimumIntegerDigits(int newValue)681 public void setMinimumIntegerDigits(int newValue) { 682 minimumIntegerDigits = Math.max(0,newValue); 683 if (minimumIntegerDigits > maximumIntegerDigits) { 684 maximumIntegerDigits = minimumIntegerDigits; 685 } 686 } 687 688 /** 689 * Returns the maximum number of digits allowed in the fraction portion of a 690 * number. 691 * 692 * @return the maximum number of digits. 693 * @see #setMaximumFractionDigits 694 */ getMaximumFractionDigits()695 public int getMaximumFractionDigits() { 696 return maximumFractionDigits; 697 } 698 699 /** 700 * Sets the maximum number of digits allowed in the fraction portion of a 701 * number. maximumFractionDigits must be ≥ minimumFractionDigits. If the 702 * new value for maximumFractionDigits is less than the current value 703 * of minimumFractionDigits, then minimumFractionDigits will also be set to 704 * the new value. 705 * 706 * @param newValue the maximum number of fraction digits to be shown; if 707 * less than zero, then zero is used. The concrete subclass may enforce an 708 * upper limit to this value appropriate to the numeric type being formatted. 709 * @see #getMaximumFractionDigits 710 */ setMaximumFractionDigits(int newValue)711 public void setMaximumFractionDigits(int newValue) { 712 maximumFractionDigits = Math.max(0,newValue); 713 if (maximumFractionDigits < minimumFractionDigits) { 714 minimumFractionDigits = maximumFractionDigits; 715 } 716 } 717 718 /** 719 * Returns the minimum number of digits allowed in the fraction portion of a 720 * number. 721 * 722 * @return the minimum number of digits 723 * @see #setMinimumFractionDigits 724 */ getMinimumFractionDigits()725 public int getMinimumFractionDigits() { 726 return minimumFractionDigits; 727 } 728 729 /** 730 * Sets the minimum number of digits allowed in the fraction portion of a 731 * number. minimumFractionDigits must be ≤ maximumFractionDigits. If the 732 * new value for minimumFractionDigits exceeds the current value 733 * of maximumFractionDigits, then maximumIntegerDigits will also be set to 734 * the new value 735 * 736 * @param newValue the minimum number of fraction digits to be shown; if 737 * less than zero, then zero is used. The concrete subclass may enforce an 738 * upper limit to this value appropriate to the numeric type being formatted. 739 * @see #getMinimumFractionDigits 740 */ setMinimumFractionDigits(int newValue)741 public void setMinimumFractionDigits(int newValue) { 742 minimumFractionDigits = Math.max(0,newValue); 743 if (maximumFractionDigits < minimumFractionDigits) { 744 maximumFractionDigits = minimumFractionDigits; 745 } 746 } 747 748 /** 749 * Gets the currency used by this number format when formatting 750 * currency values. The initial value is derived in a locale dependent 751 * way. The returned value may be null if no valid 752 * currency could be determined and no currency has been set using 753 * {@link #setCurrency(java.util.Currency) setCurrency}. 754 * <p> 755 * The default implementation throws 756 * <code>UnsupportedOperationException</code>. 757 * 758 * @return the currency used by this number format, or <code>null</code> 759 * @exception UnsupportedOperationException if the number format class 760 * doesn't implement currency formatting 761 * @since 1.4 762 */ getCurrency()763 public Currency getCurrency() { 764 throw new UnsupportedOperationException(); 765 } 766 767 /** 768 * Sets the currency used by this number format when formatting 769 * currency values. This does not update the minimum or maximum 770 * number of fraction digits used by the number format. 771 * <p> 772 * The default implementation throws 773 * <code>UnsupportedOperationException</code>. 774 * 775 * @param currency the new currency to be used by this number format 776 * @exception UnsupportedOperationException if the number format class 777 * doesn't implement currency formatting 778 * @exception NullPointerException if <code>currency</code> is null 779 * @since 1.4 780 */ setCurrency(Currency currency)781 public void setCurrency(Currency currency) { 782 throw new UnsupportedOperationException(); 783 } 784 785 /** 786 * Gets the {@link java.math.RoundingMode} used in this NumberFormat. 787 * The default implementation of this method in NumberFormat 788 * always throws {@link java.lang.UnsupportedOperationException}. 789 * Subclasses which handle different rounding modes should override 790 * this method. 791 * 792 * @exception UnsupportedOperationException The default implementation 793 * always throws this exception 794 * @return The <code>RoundingMode</code> used for this NumberFormat. 795 * @see #setRoundingMode(RoundingMode) 796 * @since 1.6 797 */ getRoundingMode()798 public RoundingMode getRoundingMode() { 799 throw new UnsupportedOperationException(); 800 } 801 802 /** 803 * Sets the {@link java.math.RoundingMode} used in this NumberFormat. 804 * The default implementation of this method in NumberFormat always 805 * throws {@link java.lang.UnsupportedOperationException}. 806 * Subclasses which handle different rounding modes should override 807 * this method. 808 * 809 * @exception UnsupportedOperationException The default implementation 810 * always throws this exception 811 * @exception NullPointerException if <code>roundingMode</code> is null 812 * @param roundingMode The <code>RoundingMode</code> to be used 813 * @see #getRoundingMode() 814 * @since 1.6 815 */ setRoundingMode(RoundingMode roundingMode)816 public void setRoundingMode(RoundingMode roundingMode) { 817 throw new UnsupportedOperationException(); 818 } 819 820 // =======================privates=============================== 821 getInstance(Locale desiredLocale, int choice)822 private static NumberFormat getInstance(Locale desiredLocale, 823 int choice) { 824 // Android-changed: Removed use of NumberFormatProvider. Switched to use ICU. 825 /* try the cache first */ 826 String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale); 827 if (numberPatterns == null) { /* cache miss */ 828 LocaleData data = LocaleData.get(desiredLocale); 829 numberPatterns = new String[4]; 830 numberPatterns[NUMBERSTYLE] = data.numberPattern; 831 numberPatterns[CURRENCYSTYLE] = data.currencyPattern; 832 numberPatterns[PERCENTSTYLE] = data.percentPattern; 833 numberPatterns[INTEGERSTYLE] = data.integerPattern; 834 /* update cache */ 835 cachedLocaleData.put(desiredLocale, numberPatterns); 836 } 837 838 DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(desiredLocale); 839 int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice; 840 DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols); 841 842 if (choice == INTEGERSTYLE) { 843 format.setMaximumFractionDigits(0); 844 format.setDecimalSeparatorAlwaysShown(false); 845 format.setParseIntegerOnly(true); 846 } else if (choice == CURRENCYSTYLE) { 847 format.adjustForCurrencyDefaultFractionDigits(); 848 } 849 850 return format; 851 } 852 853 /** 854 * First, read in the default serializable data. 855 * 856 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that 857 * the stream was written by JDK 1.1, 858 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code> 859 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>, 860 * since the <code>int</code> fields were not present in JDK 1.1. 861 * Finally, set serialVersionOnStream back to the maximum allowed value so that 862 * default serialization will work properly if this object is streamed out again. 863 * 864 * <p>If <code>minimumIntegerDigits</code> is greater than 865 * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code> 866 * is greater than <code>maximumFractionDigits</code>, then the stream data 867 * is invalid and this method throws an <code>InvalidObjectException</code>. 868 * In addition, if any of these values is negative, then this method throws 869 * an <code>InvalidObjectException</code>. 870 * 871 * @since 1.2 872 */ readObject(ObjectInputStream stream)873 private void readObject(ObjectInputStream stream) 874 throws IOException, ClassNotFoundException 875 { 876 stream.defaultReadObject(); 877 if (serialVersionOnStream < 1) { 878 // Didn't have additional int fields, reassign to use them. 879 maximumIntegerDigits = maxIntegerDigits; 880 minimumIntegerDigits = minIntegerDigits; 881 maximumFractionDigits = maxFractionDigits; 882 minimumFractionDigits = minFractionDigits; 883 } 884 if (minimumIntegerDigits > maximumIntegerDigits || 885 minimumFractionDigits > maximumFractionDigits || 886 minimumIntegerDigits < 0 || minimumFractionDigits < 0) { 887 throw new InvalidObjectException("Digit count range invalid"); 888 } 889 serialVersionOnStream = currentSerialVersion; 890 } 891 892 /** 893 * Write out the default serializable data, after first setting 894 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be 895 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code> 896 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility 897 * with the JDK 1.1 version of the stream format. 898 * 899 * @since 1.2 900 */ writeObject(ObjectOutputStream stream)901 private void writeObject(ObjectOutputStream stream) 902 throws IOException 903 { 904 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? 905 Byte.MAX_VALUE : (byte)maximumIntegerDigits; 906 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? 907 Byte.MAX_VALUE : (byte)minimumIntegerDigits; 908 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? 909 Byte.MAX_VALUE : (byte)maximumFractionDigits; 910 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? 911 Byte.MAX_VALUE : (byte)minimumFractionDigits; 912 stream.defaultWriteObject(); 913 } 914 915 /** 916 * Cache to hold the NumberPatterns of a Locale. 917 */ 918 private static final Hashtable cachedLocaleData = new Hashtable(3); 919 920 // Constants used by factory methods to specify a style of format. 921 private static final int NUMBERSTYLE = 0; 922 private static final int CURRENCYSTYLE = 1; 923 private static final int PERCENTSTYLE = 2; 924 private static final int INTEGERSTYLE = 3; 925 926 /** 927 * True if the grouping (i.e. thousands) separator is used when 928 * formatting and parsing numbers. 929 * 930 * @serial 931 * @see #isGroupingUsed 932 */ 933 private boolean groupingUsed = true; 934 935 /** 936 * The maximum number of digits allowed in the integer portion of a 937 * number. <code>maxIntegerDigits</code> must be greater than or equal to 938 * <code>minIntegerDigits</code>. 939 * <p> 940 * <strong>Note:</strong> This field exists only for serialization 941 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 942 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead. 943 * When writing to a stream, <code>maxIntegerDigits</code> is set to 944 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 945 * whichever is smaller. When reading from a stream, this field is used 946 * only if <code>serialVersionOnStream</code> is less than 1. 947 * 948 * @serial 949 * @see #getMaximumIntegerDigits 950 */ 951 private byte maxIntegerDigits = 40; 952 953 /** 954 * The minimum number of digits allowed in the integer portion of a 955 * number. <code>minimumIntegerDigits</code> must be less than or equal to 956 * <code>maximumIntegerDigits</code>. 957 * <p> 958 * <strong>Note:</strong> This field exists only for serialization 959 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 960 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead. 961 * When writing to a stream, <code>minIntegerDigits</code> is set to 962 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 963 * whichever is smaller. When reading from a stream, this field is used 964 * only if <code>serialVersionOnStream</code> is less than 1. 965 * 966 * @serial 967 * @see #getMinimumIntegerDigits 968 */ 969 private byte minIntegerDigits = 1; 970 971 /** 972 * The maximum number of digits allowed in the fractional portion of a 973 * number. <code>maximumFractionDigits</code> must be greater than or equal to 974 * <code>minimumFractionDigits</code>. 975 * <p> 976 * <strong>Note:</strong> This field exists only for serialization 977 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 978 * <code>int</code> field <code>maximumFractionDigits</code> is used instead. 979 * When writing to a stream, <code>maxFractionDigits</code> is set to 980 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 981 * whichever is smaller. When reading from a stream, this field is used 982 * only if <code>serialVersionOnStream</code> is less than 1. 983 * 984 * @serial 985 * @see #getMaximumFractionDigits 986 */ 987 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits 988 989 /** 990 * The minimum number of digits allowed in the fractional portion of a 991 * number. <code>minimumFractionDigits</code> must be less than or equal to 992 * <code>maximumFractionDigits</code>. 993 * <p> 994 * <strong>Note:</strong> This field exists only for serialization 995 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 996 * <code>int</code> field <code>minimumFractionDigits</code> is used instead. 997 * When writing to a stream, <code>minFractionDigits</code> is set to 998 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 999 * whichever is smaller. When reading from a stream, this field is used 1000 * only if <code>serialVersionOnStream</code> is less than 1. 1001 * 1002 * @serial 1003 * @see #getMinimumFractionDigits 1004 */ 1005 private byte minFractionDigits = 0; 1006 1007 /** 1008 * True if this format will parse numbers as integers only. 1009 * 1010 * @serial 1011 * @see #isParseIntegerOnly 1012 */ 1013 private boolean parseIntegerOnly = false; 1014 1015 // new fields for 1.2. byte is too small for integer digits. 1016 1017 /** 1018 * The maximum number of digits allowed in the integer portion of a 1019 * number. <code>maximumIntegerDigits</code> must be greater than or equal to 1020 * <code>minimumIntegerDigits</code>. 1021 * 1022 * @serial 1023 * @since 1.2 1024 * @see #getMaximumIntegerDigits 1025 */ 1026 private int maximumIntegerDigits = 40; 1027 1028 /** 1029 * The minimum number of digits allowed in the integer portion of a 1030 * number. <code>minimumIntegerDigits</code> must be less than or equal to 1031 * <code>maximumIntegerDigits</code>. 1032 * 1033 * @serial 1034 * @since 1.2 1035 * @see #getMinimumIntegerDigits 1036 */ 1037 private int minimumIntegerDigits = 1; 1038 1039 /** 1040 * The maximum number of digits allowed in the fractional portion of a 1041 * number. <code>maximumFractionDigits</code> must be greater than or equal to 1042 * <code>minimumFractionDigits</code>. 1043 * 1044 * @serial 1045 * @since 1.2 1046 * @see #getMaximumFractionDigits 1047 */ 1048 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits 1049 1050 /** 1051 * The minimum number of digits allowed in the fractional portion of a 1052 * number. <code>minimumFractionDigits</code> must be less than or equal to 1053 * <code>maximumFractionDigits</code>. 1054 * 1055 * @serial 1056 * @since 1.2 1057 * @see #getMinimumFractionDigits 1058 */ 1059 private int minimumFractionDigits = 0; 1060 1061 static final int currentSerialVersion = 1; 1062 1063 /** 1064 * Describes the version of <code>NumberFormat</code> present on the stream. 1065 * Possible values are: 1066 * <ul> 1067 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format. 1068 * In this version, the <code>int</code> fields such as 1069 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code> 1070 * fields such as <code>maxIntegerDigits</code> are used instead. 1071 * 1072 * <li><b>1</b>: the 1.2 version of the stream format. The values of the 1073 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored, 1074 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code> 1075 * are used instead. 1076 * </ul> 1077 * When streaming out a <code>NumberFormat</code>, the most recent format 1078 * (corresponding to the highest allowable <code>serialVersionOnStream</code>) 1079 * is always written. 1080 * 1081 * @serial 1082 * @since 1.2 1083 */ 1084 private int serialVersionOnStream = currentSerialVersion; 1085 1086 // Removed "implements Cloneable" clause. Needs to update serialization 1087 // ID for backward compatibility. 1088 static final long serialVersionUID = -2308460125733713944L; 1089 1090 1091 // 1092 // class for AttributedCharacterIterator attributes 1093 // 1094 /** 1095 * Defines constants that are used as attribute keys in the 1096 * <code>AttributedCharacterIterator</code> returned 1097 * from <code>NumberFormat.formatToCharacterIterator</code> and as 1098 * field identifiers in <code>FieldPosition</code>. 1099 * 1100 * @since 1.4 1101 */ 1102 public static class Field extends Format.Field { 1103 1104 // Proclaim serial compatibility with 1.4 FCS 1105 private static final long serialVersionUID = 7494728892700160890L; 1106 1107 // table of all instances in this class, used by readResolve 1108 private static final Map<String, Field> instanceMap = new HashMap<>(11); 1109 1110 /** 1111 * Creates a Field instance with the specified 1112 * name. 1113 * 1114 * @param name Name of the attribute 1115 */ Field(String name)1116 protected Field(String name) { 1117 super(name); 1118 if (this.getClass() == NumberFormat.Field.class) { 1119 instanceMap.put(name, this); 1120 } 1121 } 1122 1123 /** 1124 * Resolves instances being deserialized to the predefined constants. 1125 * 1126 * @throws InvalidObjectException if the constant could not be resolved. 1127 * @return resolved NumberFormat.Field constant 1128 */ 1129 @Override readResolve()1130 protected Object readResolve() throws InvalidObjectException { 1131 if (this.getClass() != NumberFormat.Field.class) { 1132 throw new InvalidObjectException("subclass didn't correctly implement readResolve"); 1133 } 1134 1135 Object instance = instanceMap.get(getName()); 1136 if (instance != null) { 1137 return instance; 1138 } else { 1139 throw new InvalidObjectException("unknown attribute name"); 1140 } 1141 } 1142 1143 /** 1144 * Constant identifying the integer field. 1145 */ 1146 public static final Field INTEGER = new Field("integer"); 1147 1148 /** 1149 * Constant identifying the fraction field. 1150 */ 1151 public static final Field FRACTION = new Field("fraction"); 1152 1153 /** 1154 * Constant identifying the exponent field. 1155 */ 1156 public static final Field EXPONENT = new Field("exponent"); 1157 1158 /** 1159 * Constant identifying the decimal separator field. 1160 */ 1161 public static final Field DECIMAL_SEPARATOR = 1162 new Field("decimal separator"); 1163 1164 /** 1165 * Constant identifying the sign field. 1166 */ 1167 public static final Field SIGN = new Field("sign"); 1168 1169 /** 1170 * Constant identifying the grouping separator field. 1171 */ 1172 public static final Field GROUPING_SEPARATOR = 1173 new Field("grouping separator"); 1174 1175 /** 1176 * Constant identifying the exponent symbol field. 1177 */ 1178 public static final Field EXPONENT_SYMBOL = new 1179 Field("exponent symbol"); 1180 1181 /** 1182 * Constant identifying the percent field. 1183 */ 1184 public static final Field PERCENT = new Field("percent"); 1185 1186 /** 1187 * Constant identifying the permille field. 1188 */ 1189 public static final Field PERMILLE = new Field("per mille"); 1190 1191 /** 1192 * Constant identifying the currency field. 1193 */ 1194 public static final Field CURRENCY = new Field("currency"); 1195 1196 /** 1197 * Constant identifying the exponent sign field. 1198 */ 1199 public static final Field EXPONENT_SIGN = new Field("exponent sign"); 1200 } 1201 } 1202