1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2017 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 package android.icu.text; 5 6 import java.io.IOException; 7 import java.io.ObjectInputStream; 8 import java.io.ObjectOutputStream; 9 import java.io.ObjectStreamField; 10 import java.math.BigInteger; 11 import java.math.RoundingMode; 12 import java.text.AttributedCharacterIterator; 13 import java.text.FieldPosition; 14 import java.text.ParseException; 15 import java.text.ParsePosition; 16 17 import android.icu.impl.number.AffixUtils; 18 import android.icu.impl.number.DecimalFormatProperties; 19 import android.icu.impl.number.Padder.PadPosition; 20 import android.icu.impl.number.Parse; 21 import android.icu.impl.number.PatternStringParser; 22 import android.icu.impl.number.PatternStringUtils; 23 import android.icu.lang.UCharacter; 24 import android.icu.math.BigDecimal; 25 import android.icu.math.MathContext; 26 import android.icu.number.FormattedNumber; 27 import android.icu.number.LocalizedNumberFormatter; 28 import android.icu.number.NumberFormatter; 29 import android.icu.text.PluralRules.IFixedDecimal; 30 import android.icu.util.Currency; 31 import android.icu.util.Currency.CurrencyUsage; 32 import android.icu.util.CurrencyAmount; 33 import android.icu.util.ULocale; 34 import android.icu.util.ULocale.Category; 35 36 /** 37 * <strong>[icu enhancement]</strong> ICU's replacement for {@link java.text.DecimalFormat}. Methods, fields, and other functionality specific to ICU are labeled '<strong>[icu]</strong>'. <code>DecimalFormat</code> is the primary 38 * concrete subclass of {@link NumberFormat}. It has a variety of features designed to make it 39 * possible to parse and format numbers in any locale, including support for Western, Arabic, or 40 * Indic digits. It supports different flavors of numbers, including integers ("123"), fixed-point 41 * numbers ("123.4"), scientific notation ("1.23E4"), percentages ("12%"), and currency amounts 42 * ("$123.00", "USD123.00", "123.00 US dollars"). All of these flavors can be easily localized. 43 * 44 * <p>To obtain a number formatter for a specific locale (including the default locale), call one of 45 * NumberFormat's factory methods such as {@link NumberFormat#getInstance}. Do not call 46 * DecimalFormat constructors directly unless you know what you are doing. 47 * 48 * <p>DecimalFormat aims to comply with the specification <a 49 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS #35</a>. Read 50 * the specification for more information on how all the properties in DecimalFormat fit together. 51 * 52 * <p><strong>NOTE:</strong> Starting in ICU 60, there is a new set of APIs for localized number 53 * formatting that are designed to be an improvement over DecimalFormat. New users are discouraged 54 * from using DecimalFormat. For more information, see the package android.icu.number. 55 * 56 * <h3>Example Usage</h3> 57 * 58 * <p>Customize settings on a DecimalFormat instance from the NumberFormat factory: 59 * 60 * <blockquote> 61 * 62 * <pre> 63 * NumberFormat f = NumberFormat.getInstance(loc); 64 * if (f instanceof DecimalFormat) { 65 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); 66 * ((DecimalFormat) f).setMinimumGroupingDigits(2); 67 * } 68 * </pre> 69 * 70 * </blockquote> 71 * 72 * <p>Quick and dirty print out a number using the localized number, currency, and percent format 73 * for each locale: 74 * 75 * <blockquote> 76 * 77 * <pre> 78 * for (ULocale uloc : ULocale.getAvailableLocales()) { 79 * System.out.print(uloc + ":\t"); 80 * System.out.print(NumberFormat.getInstance(uloc).format(1.23)); 81 * System.out.print("\t"); 82 * System.out.print(NumberFormat.getCurrencyInstance(uloc).format(1.23)); 83 * System.out.print("\t"); 84 * System.out.print(NumberFormat.getPercentInstance(uloc).format(1.23)); 85 * System.out.println(); 86 * } 87 * </pre> 88 * 89 * </blockquote> 90 * 91 * <h3>Properties and Symbols</h3> 92 * 93 * <p>A DecimalFormat object encapsulates a set of <em>properties</em> and a set of 94 * <em>symbols</em>. Grouping size, rounding mode, and affixes are examples of properties. Locale 95 * digits and the characters used for grouping and decimal separators are examples of symbols. 96 * 97 * <p>To set a custom set of symbols, use {@link #setDecimalFormatSymbols}. Use the various other 98 * setters in this class to set custom values for the properties. 99 * 100 * <h3>Rounding</h3> 101 * 102 * <p>DecimalFormat provides three main strategies to specify the position at which numbers should 103 * be rounded: 104 * 105 * <ol> 106 * <li><strong>Magnitude:</strong> Display a fixed number of fraction digits; this is the most 107 * common form. 108 * <li><strong>Increment:</strong> Round numbers to the closest multiple of a certain increment, 109 * such as 0.05. This is common in currencies. 110 * <li><strong>Significant Digits:</strong> Round numbers such that a fixed number of nonzero 111 * digits are shown. This is most common in scientific notation. 112 * </ol> 113 * 114 * <p>It is not possible to specify more than one rounding strategy. For example, setting a rounding 115 * increment in conjunction with significant digits results in undefined behavior. 116 * 117 * <p>It is also possible to specify the <em>rounding mode</em> to use. The default rounding mode is 118 * "half even", which rounds numbers to their closest increment, with ties broken in favor of 119 * trailing numbers being even. For more information, see {@link #setRoundingMode} and <a 120 * href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes">the ICU User 121 * Guide</a>. 122 * 123 * <h3>Pattern Strings</h3> 124 * 125 * <p>A <em>pattern string</em> is a way to serialize some of the available properties for decimal 126 * formatting. However, not all properties are capable of being serialized into a pattern string; 127 * see {@link #applyPattern} for more information. 128 * 129 * <p>Most users should not need to interface with pattern strings directly. 130 * 131 * <p>ICU DecimalFormat aims to follow the specification for pattern strings in <a 132 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS #35</a>. 133 * Refer to that specification for more information on pattern string syntax. 134 * 135 * <h4>Pattern String BNF</h4> 136 * 137 * The following BNF is used when parsing the pattern string into property values: 138 * 139 * <pre> 140 * pattern := subpattern (';' subpattern)? 141 * subpattern := prefix? number exponent? suffix? 142 * number := (integer ('.' fraction)?) | sigDigits 143 * prefix := '\u0000'..'\uFFFD' - specialCharacters 144 * suffix := '\u0000'..'\uFFFD' - specialCharacters 145 * integer := '#'* '0'* '0' 146 * fraction := '0'* '#'* 147 * sigDigits := '#'* '@' '@'* '#'* 148 * exponent := 'E' '+'? '0'* '0' 149 * padSpec := '*' padChar 150 * padChar := '\u0000'..'\uFFFD' - quote 151 *   152 * Notation: 153 * X* 0 or more instances of X 154 * X? 0 or 1 instances of X 155 * X|Y either X or Y 156 * C..D any character from C up to D, inclusive 157 * S-T characters in S, except those in T 158 * </pre> 159 * 160 * <p>The first subpattern is for positive numbers. The second (optional) subpattern is for negative 161 * numbers. 162 * 163 * <p>Not indicated in the BNF syntax above: 164 * 165 * <ul> 166 * <li>The grouping separator ',' can occur inside the integer and sigDigits elements, between any 167 * two pattern characters of that element, as long as the integer or sigDigits element is not 168 * followed by the exponent element. 169 * <li>Two grouping intervals are recognized: That between the decimal point and the first 170 * grouping symbol, and that between the first and second grouping symbols. These intervals 171 * are identical in most locales, but in some locales they differ. For example, the pattern 172 * "#,##,###" formats the number 123456789 as "12,34,56,789". 173 * <li>The pad specifier <code>padSpec</code> may appear before the prefix, after the prefix, 174 * before the suffix, after the suffix, or not at all. 175 * <li>In place of '0', the digits '1' through '9' may be used to indicate a rounding increment. 176 * </ul> 177 * 178 * <h3>Parsing</h3> 179 * 180 * <p>DecimalFormat aims to be able to parse anything that it can output as a formatted string. 181 * 182 * <p>There are two primary parse modes: <em>lenient</em> and <em>strict</em>. Lenient mode should 183 * be used if the goal is to parse user input to a number; strict mode should be used if the goal is 184 * validation. The default is lenient mode. For more information, see {@link #setParseStrict}. 185 * 186 * <p><code>DecimalFormat</code> parses all Unicode characters that represent decimal digits, as 187 * defined by {@link UCharacter#digit}. In addition, <code>DecimalFormat</code> also recognizes as 188 * digits the ten consecutive characters starting with the localized zero digit defined in the 189 * {@link DecimalFormatSymbols} object. During formatting, the {@link DecimalFormatSymbols}-based 190 * digits are output. 191 * 192 * <p>Grouping separators are ignored in lenient mode (default). In strict mode, grouping separators 193 * must match the locale-specified grouping sizes. 194 * 195 * <p>When using {@link #parseCurrency}, all currencies are accepted, not just the currency 196 * currently set in the formatter. In addition, the formatter is able to parse every currency style 197 * format for a particular locale no matter which style the formatter is constructed with. For 198 * example, a formatter instance gotten from NumberFormat.getInstance(ULocale, 199 * NumberFormat.CURRENCYSTYLE) can parse both "USD1.00" and "3.00 US dollars". 200 * 201 * <p>Whitespace characters (lenient mode) and bidi control characters (lenient and strict mode), 202 * collectively called "ignorables", do not need to match in identity or quantity between the 203 * pattern string and the input string. For example, the pattern "# %" matches "35 %" (with a single 204 * space), "35%" (with no space), "35 %" (with a non-breaking space), and "35 %" (with 205 * multiple spaces). Arbitrary ignorables are also allowed at boundaries between the parts of the 206 * number: prefix, number, exponent separator, and suffix. Ignorable whitespace characters are those 207 * having the Unicode "blank" property for regular expressions, defined in UTS #18 Annex C, which is 208 * "horizontal" whitespace, like spaces and tabs, but not "vertical" whitespace, like line breaks. 209 * 210 * <p>If {@link #parse(String, ParsePosition)} fails to parse a string, it returns <code>null</code> 211 * and leaves the parse position unchanged. The convenience method {@link #parse(String)} indicates 212 * parse failure by throwing a {@link java.text.ParseException}. 213 * 214 * <p>Under the hood, a state table parsing engine is used. To debug a parsing failure during 215 * development, use the following pattern to print details about the state table transitions: 216 * 217 * <pre> 218 * android.icu.impl.number.Parse.DEBUGGING = true; 219 * df.parse("123.45", ppos); 220 * android.icu.impl.number.Parse.DEBUGGING = false; 221 * </pre> 222 * 223 * <h3>Thread Safety and Best Practices</h3> 224 * 225 * <p>Starting with ICU 59, instances of DecimalFormat are thread-safe. 226 * 227 * <p>Under the hood, DecimalFormat maintains an immutable formatter object that is rebuilt whenever 228 * any of the property setters are called. It is therefore best practice to call property setters 229 * only during construction and not when formatting numbers online. 230 * 231 * @see java.text.Format 232 * @see NumberFormat 233 */ 234 public class DecimalFormat extends NumberFormat { 235 236 /** New serialization in ICU 59: declare different version from ICU 58. */ 237 private static final long serialVersionUID = 864413376551465018L; 238 239 /** 240 * One non-transient field such that deserialization can determine the version of the class. This 241 * field has existed since the very earliest versions of DecimalFormat. 242 */ 243 @SuppressWarnings("unused") 244 private final int serialVersionOnStream = 5; 245 246 //=====================================================================================// 247 // INSTANCE FIELDS // 248 //=====================================================================================// 249 250 // Fields are package-private, so that subclasses can use them. 251 // properties should be final, but clone won't work if we make it final. 252 // All fields are transient because custom serialization is used. 253 254 /** 255 * The property bag corresponding to user-specified settings and settings from the pattern string. 256 * In principle this should be final, but serialize and clone won't work if it is final. Does not 257 * need to be volatile because the reference never changes. 258 */ 259 /* final */ transient DecimalFormatProperties properties; 260 261 /** 262 * The symbols for the current locale. Volatile because threads may read and write at the same 263 * time. 264 */ 265 transient volatile DecimalFormatSymbols symbols; 266 267 /** 268 * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link 269 * #format} method uses the formatter directly without needing to synchronize. Volatile because 270 * threads may read and write at the same time. 271 */ 272 transient volatile LocalizedNumberFormatter formatter; 273 274 /** 275 * The effective properties as exported from the formatter object. Volatile because threads may 276 * read and write at the same time. 277 */ 278 transient volatile DecimalFormatProperties exportedProperties; 279 280 //=====================================================================================// 281 // CONSTRUCTORS // 282 //=====================================================================================// 283 284 /** 285 * Creates a DecimalFormat based on the number pattern and symbols for the default locale. This is 286 * a convenient way to obtain a DecimalFormat instance when internationalization is not the main 287 * concern. 288 * 289 * <p>Most users should call the factory methods on NumberFormat, such as {@link 290 * NumberFormat#getNumberInstance}, which return localized formatter objects, instead of the 291 * DecimalFormat constructors. 292 * 293 * @see NumberFormat#getInstance 294 * @see NumberFormat#getNumberInstance 295 * @see NumberFormat#getCurrencyInstance 296 * @see NumberFormat#getPercentInstance 297 * @see Category#FORMAT 298 */ 299 public DecimalFormat() { 300 // Use the locale's default pattern 301 ULocale def = ULocale.getDefault(ULocale.Category.FORMAT); 302 String pattern = getPattern(def, NumberFormat.NUMBERSTYLE); 303 symbols = getDefaultSymbols(); 304 properties = new DecimalFormatProperties(); 305 exportedProperties = new DecimalFormatProperties(); 306 // Regression: ignore pattern rounding information if the pattern has currency symbols. 307 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_IF_CURRENCY); 308 refreshFormatter(); 309 } 310 311 /** 312 * Creates a DecimalFormat based on the given pattern, using symbols for the default locale. This 313 * is a convenient way to obtain a DecimalFormat instance when internationalization is not the 314 * main concern. 315 * 316 * <p>Most users should call the factory methods on NumberFormat, such as {@link 317 * NumberFormat#getNumberInstance}, which return localized formatter objects, instead of the 318 * DecimalFormat constructors. 319 * 320 * @param pattern A pattern string such as "#,##0.00" conforming to <a 321 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS 322 * #35</a>. 323 * @throws IllegalArgumentException if the given pattern is invalid. 324 * @see NumberFormat#getInstance 325 * @see NumberFormat#getNumberInstance 326 * @see NumberFormat#getCurrencyInstance 327 * @see NumberFormat#getPercentInstance 328 * @see Category#FORMAT 329 */ 330 public DecimalFormat(String pattern) { 331 symbols = getDefaultSymbols(); 332 properties = new DecimalFormatProperties(); 333 exportedProperties = new DecimalFormatProperties(); 334 // Regression: ignore pattern rounding information if the pattern has currency symbols. 335 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_IF_CURRENCY); 336 refreshFormatter(); 337 } 338 339 /** 340 * Creates a DecimalFormat based on the given pattern and symbols. Use this constructor if you 341 * want complete control over the behavior of the formatter. 342 * 343 * <p>Most users should call the factory methods on NumberFormat, such as {@link 344 * NumberFormat#getNumberInstance}, which return localized formatter objects, instead of the 345 * DecimalFormat constructors. 346 * 347 * @param pattern A pattern string such as "#,##0.00" conforming to <a 348 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS 349 * #35</a>. 350 * @param symbols The set of symbols to be used. 351 * @exception IllegalArgumentException if the given pattern is invalid 352 * @see NumberFormat#getInstance 353 * @see NumberFormat#getNumberInstance 354 * @see NumberFormat#getCurrencyInstance 355 * @see NumberFormat#getPercentInstance 356 * @see DecimalFormatSymbols 357 */ 358 public DecimalFormat(String pattern, DecimalFormatSymbols symbols) { 359 this.symbols = (DecimalFormatSymbols) symbols.clone(); 360 properties = new DecimalFormatProperties(); 361 exportedProperties = new DecimalFormatProperties(); 362 // Regression: ignore pattern rounding information if the pattern has currency symbols. 363 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_IF_CURRENCY); 364 refreshFormatter(); 365 } 366 367 /** 368 * Creates a DecimalFormat based on the given pattern and symbols, with additional control over 369 * the behavior of currency. The style argument determines whether currency rounding rules should 370 * override the pattern, and the {@link CurrencyPluralInfo} object is used for customizing the 371 * plural forms used for currency long names. 372 * 373 * <p>Most users should call the factory methods on NumberFormat, such as {@link 374 * NumberFormat#getNumberInstance}, which return localized formatter objects, instead of the 375 * DecimalFormat constructors. 376 * 377 * @param pattern a non-localized pattern string 378 * @param symbols the set of symbols to be used 379 * @param infoInput the information used for currency plural format, including currency plural 380 * patterns and plural rules. 381 * @param style the decimal formatting style, it is one of the following values: 382 * NumberFormat.NUMBERSTYLE; NumberFormat.CURRENCYSTYLE; NumberFormat.PERCENTSTYLE; 383 * NumberFormat.SCIENTIFICSTYLE; NumberFormat.INTEGERSTYLE; NumberFormat.ISOCURRENCYSTYLE; 384 * NumberFormat.PLURALCURRENCYSTYLE; 385 */ 386 public DecimalFormat( 387 String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput, int style) { 388 this(pattern, symbols, style); 389 properties.setCurrencyPluralInfo(infoInput); 390 refreshFormatter(); 391 } 392 393 /** Package-private constructor used by NumberFormat. */ 394 DecimalFormat(String pattern, DecimalFormatSymbols symbols, int choice) { 395 this.symbols = (DecimalFormatSymbols) symbols.clone(); 396 properties = new DecimalFormatProperties(); 397 exportedProperties = new DecimalFormatProperties(); 398 // If choice is a currency type, ignore the rounding information. 399 if (choice == CURRENCYSTYLE 400 || choice == ISOCURRENCYSTYLE 401 || choice == ACCOUNTINGCURRENCYSTYLE 402 || choice == CASHCURRENCYSTYLE 403 || choice == STANDARDCURRENCYSTYLE 404 || choice == PLURALCURRENCYSTYLE) { 405 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_ALWAYS); 406 } else { 407 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_IF_CURRENCY); 408 } 409 refreshFormatter(); 410 } 411 412 private static DecimalFormatSymbols getDefaultSymbols() { 413 return DecimalFormatSymbols.getInstance(); 414 } 415 416 /** 417 * Parses the given pattern string and overwrites the settings specified in the pattern string. 418 * The properties corresponding to the following setters are overwritten, either with their 419 * default values or with the value specified in the pattern string: 420 * 421 * <ol> 422 * <li>{@link #setDecimalSeparatorAlwaysShown} 423 * <li>{@link #setExponentSignAlwaysShown} 424 * <li>{@link #setFormatWidth} 425 * <li>{@link #setGroupingSize} 426 * <li>{@link #setMultiplier} (percent/permille) 427 * <li>{@link #setMaximumFractionDigits} 428 * <li>{@link #setMaximumIntegerDigits} 429 * <li>{@link #setMaximumSignificantDigits} 430 * <li>{@link #setMinimumExponentDigits} 431 * <li>{@link #setMinimumFractionDigits} 432 * <li>{@link #setMinimumIntegerDigits} 433 * <li>{@link #setMinimumSignificantDigits} 434 * <li>{@link #setPadPosition} 435 * <li>{@link #setPadCharacter} 436 * <li>{@link #setRoundingIncrement} 437 * <li>{@link #setSecondaryGroupingSize} 438 * </ol> 439 * 440 * All other settings remain untouched. 441 * 442 * <p>For more information on pattern strings, see <a 443 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS #35</a>. 444 */ 445 public synchronized void applyPattern(String pattern) { 446 setPropertiesFromPattern(pattern, PatternStringParser.IGNORE_ROUNDING_NEVER); 447 // Backwards compatibility: clear out user-specified prefix and suffix, 448 // as well as CurrencyPluralInfo. 449 properties.setPositivePrefix(null); 450 properties.setNegativePrefix(null); 451 properties.setPositiveSuffix(null); 452 properties.setNegativeSuffix(null); 453 properties.setCurrencyPluralInfo(null); 454 refreshFormatter(); 455 } 456 457 /** 458 * Converts the given string to standard notation and then parses it using {@link #applyPattern}. 459 * This method is provided for backwards compatibility and should not be used in new projects. 460 * 461 * <p>Localized notation means that instead of using generic placeholders in the pattern, you use 462 * the corresponding locale-specific characters instead. For example, in locale <em>fr-FR</em>, 463 * the period in the pattern "0.000" means "decimal" in standard notation (as it does in every 464 * other locale), but it means "grouping" in localized notation. 465 * 466 * @param localizedPattern The pattern string in localized notation. 467 */ 468 public synchronized void applyLocalizedPattern(String localizedPattern) { 469 String pattern = PatternStringUtils.convertLocalized(localizedPattern, symbols, false); 470 applyPattern(pattern); 471 } 472 473 //=====================================================================================// 474 // CLONE AND SERIALIZE // 475 //=====================================================================================// 476 477 /***/ 478 @Override 479 public Object clone() { 480 DecimalFormat other = (DecimalFormat) super.clone(); 481 other.symbols = (DecimalFormatSymbols) symbols.clone(); 482 other.properties = properties.clone(); 483 other.exportedProperties = new DecimalFormatProperties(); 484 other.refreshFormatter(); 485 return other; 486 } 487 488 /** 489 * Custom serialization: save property bag and symbols; the formatter object can be re-created 490 * from just that amount of information. 491 */ 492 private synchronized void writeObject(ObjectOutputStream oos) throws IOException { 493 // ICU 59 custom serialization. 494 // Write class metadata and serialVersionOnStream field: 495 oos.defaultWriteObject(); 496 // Extra int for possible future use: 497 oos.writeInt(0); 498 // 1) Property Bag 499 oos.writeObject(properties); 500 // 2) DecimalFormatSymbols 501 oos.writeObject(symbols); 502 } 503 504 /** 505 * Custom serialization: re-create object from serialized property bag and symbols. Also supports 506 * reading from the legacy (pre-ICU4J 59) format and converting it to the new form. 507 */ 508 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { 509 ObjectInputStream.GetField fieldGetter = ois.readFields(); 510 ObjectStreamField[] serializedFields = fieldGetter.getObjectStreamClass().getFields(); 511 int serialVersion = fieldGetter.get("serialVersionOnStream", -1); 512 513 if (serialVersion > 5) { 514 throw new IOException( 515 "Cannot deserialize newer android.icu.text.DecimalFormat (v" + serialVersion + ")"); 516 } else if (serialVersion == 5) { 517 ///// ICU 59+ SERIALIZATION FORMAT ///// 518 // We expect this field and no other fields: 519 if (serializedFields.length > 1) { 520 throw new IOException("Too many fields when reading serial version 5"); 521 } 522 // Extra int for possible future use: 523 ois.readInt(); 524 // 1) Property Bag 525 Object serializedProperties = ois.readObject(); 526 if (serializedProperties instanceof DecimalFormatProperties) { 527 // ICU 60+ 528 properties = (DecimalFormatProperties) serializedProperties; 529 } else { 530 // ICU 59 531 properties = ((android.icu.impl.number.Properties) serializedProperties).getInstance(); 532 } 533 // 2) DecimalFormatSymbols 534 symbols = (DecimalFormatSymbols) ois.readObject(); 535 // Re-build transient fields 536 exportedProperties = new DecimalFormatProperties(); 537 refreshFormatter(); 538 } else { 539 ///// LEGACY SERIALIZATION FORMAT ///// 540 properties = new DecimalFormatProperties(); 541 // Loop through the fields. Not all fields necessarily exist in the serialization. 542 String pp = null, ppp = null, ps = null, psp = null; 543 String np = null, npp = null, ns = null, nsp = null; 544 for (ObjectStreamField field : serializedFields) { 545 String name = field.getName(); 546 if (name.equals("decimalSeparatorAlwaysShown")) { 547 setDecimalSeparatorAlwaysShown(fieldGetter.get("decimalSeparatorAlwaysShown", false)); 548 } else if (name.equals("exponentSignAlwaysShown")) { 549 setExponentSignAlwaysShown(fieldGetter.get("exponentSignAlwaysShown", false)); 550 } else if (name.equals("formatWidth")) { 551 setFormatWidth(fieldGetter.get("formatWidth", 0)); 552 } else if (name.equals("groupingSize")) { 553 setGroupingSize(fieldGetter.get("groupingSize", (byte) 3)); 554 } else if (name.equals("groupingSize2")) { 555 setSecondaryGroupingSize(fieldGetter.get("groupingSize2", (byte) 0)); 556 } else if (name.equals("maxSignificantDigits")) { 557 setMaximumSignificantDigits(fieldGetter.get("maxSignificantDigits", 6)); 558 } else if (name.equals("minExponentDigits")) { 559 setMinimumExponentDigits(fieldGetter.get("minExponentDigits", (byte) 0)); 560 } else if (name.equals("minSignificantDigits")) { 561 setMinimumSignificantDigits(fieldGetter.get("minSignificantDigits", 1)); 562 } else if (name.equals("multiplier")) { 563 setMultiplier(fieldGetter.get("multiplier", 1)); 564 } else if (name.equals("pad")) { 565 setPadCharacter(fieldGetter.get("pad", '\u0020')); 566 } else if (name.equals("padPosition")) { 567 setPadPosition(fieldGetter.get("padPosition", 0)); 568 } else if (name.equals("parseBigDecimal")) { 569 setParseBigDecimal(fieldGetter.get("parseBigDecimal", false)); 570 } else if (name.equals("parseRequireDecimalPoint")) { 571 setDecimalPatternMatchRequired(fieldGetter.get("parseRequireDecimalPoint", false)); 572 } else if (name.equals("roundingMode")) { 573 setRoundingMode(fieldGetter.get("roundingMode", 0)); 574 } else if (name.equals("useExponentialNotation")) { 575 setScientificNotation(fieldGetter.get("useExponentialNotation", false)); 576 } else if (name.equals("useSignificantDigits")) { 577 setSignificantDigitsUsed(fieldGetter.get("useSignificantDigits", false)); 578 } else if (name.equals("currencyPluralInfo")) { 579 setCurrencyPluralInfo((CurrencyPluralInfo) fieldGetter.get("currencyPluralInfo", null)); 580 } else if (name.equals("mathContext")) { 581 setMathContextICU((MathContext) fieldGetter.get("mathContext", null)); 582 } else if (name.equals("negPrefixPattern")) { 583 npp = (String) fieldGetter.get("negPrefixPattern", null); 584 } else if (name.equals("negSuffixPattern")) { 585 nsp = (String) fieldGetter.get("negSuffixPattern", null); 586 } else if (name.equals("negativePrefix")) { 587 np = (String) fieldGetter.get("negativePrefix", null); 588 } else if (name.equals("negativeSuffix")) { 589 ns = (String) fieldGetter.get("negativeSuffix", null); 590 } else if (name.equals("posPrefixPattern")) { 591 ppp = (String) fieldGetter.get("posPrefixPattern", null); 592 } else if (name.equals("posSuffixPattern")) { 593 psp = (String) fieldGetter.get("posSuffixPattern", null); 594 } else if (name.equals("positivePrefix")) { 595 pp = (String) fieldGetter.get("positivePrefix", null); 596 } else if (name.equals("positiveSuffix")) { 597 ps = (String) fieldGetter.get("positiveSuffix", null); 598 } else if (name.equals("roundingIncrement")) { 599 setRoundingIncrement((java.math.BigDecimal) fieldGetter.get("roundingIncrement", null)); 600 } else if (name.equals("symbols")) { 601 setDecimalFormatSymbols((DecimalFormatSymbols) fieldGetter.get("symbols", null)); 602 } else { 603 // The following fields are ignored: 604 // "PARSE_MAX_EXPONENT" 605 // "currencySignCount" 606 // "style" 607 // "attributes" 608 // "currencyChoice" 609 // "formatPattern" 610 // "currencyUsage" => ignore this because the old code puts currencyUsage directly into min/max fraction. 611 } 612 } 613 // Resolve affixes 614 if (npp == null) { 615 properties.setNegativePrefix(np); 616 } else { 617 properties.setNegativePrefixPattern(npp); 618 } 619 if (nsp == null) { 620 properties.setNegativeSuffix(ns); 621 } else { 622 properties.setNegativeSuffixPattern(nsp); 623 } 624 if (ppp == null) { 625 properties.setPositivePrefix(pp); 626 } else { 627 properties.setPositivePrefixPattern(ppp); 628 } 629 if (psp == null) { 630 properties.setPositiveSuffix(ps); 631 } else { 632 properties.setPositiveSuffixPattern(psp); 633 } 634 // Extract values from parent NumberFormat class. Have to use reflection here. 635 java.lang.reflect.Field getter; 636 try { 637 getter = NumberFormat.class.getDeclaredField("groupingUsed"); 638 getter.setAccessible(true); 639 setGroupingUsed((Boolean) getter.get(this)); 640 getter = NumberFormat.class.getDeclaredField("parseIntegerOnly"); 641 getter.setAccessible(true); 642 setParseIntegerOnly((Boolean) getter.get(this)); 643 getter = NumberFormat.class.getDeclaredField("maximumIntegerDigits"); 644 getter.setAccessible(true); 645 setMaximumIntegerDigits((Integer) getter.get(this)); 646 getter = NumberFormat.class.getDeclaredField("minimumIntegerDigits"); 647 getter.setAccessible(true); 648 setMinimumIntegerDigits((Integer) getter.get(this)); 649 getter = NumberFormat.class.getDeclaredField("maximumFractionDigits"); 650 getter.setAccessible(true); 651 setMaximumFractionDigits((Integer) getter.get(this)); 652 getter = NumberFormat.class.getDeclaredField("minimumFractionDigits"); 653 getter.setAccessible(true); 654 setMinimumFractionDigits((Integer) getter.get(this)); 655 getter = NumberFormat.class.getDeclaredField("currency"); 656 getter.setAccessible(true); 657 setCurrency((Currency) getter.get(this)); 658 getter = NumberFormat.class.getDeclaredField("parseStrict"); 659 getter.setAccessible(true); 660 setParseStrict((Boolean) getter.get(this)); 661 } catch (IllegalArgumentException e) { 662 throw new IOException(e); 663 } catch (IllegalAccessException e) { 664 throw new IOException(e); 665 } catch (NoSuchFieldException e) { 666 throw new IOException(e); 667 } catch (SecurityException e) { 668 throw new IOException(e); 669 } 670 // Finish initialization 671 if (symbols == null) { 672 symbols = getDefaultSymbols(); 673 } 674 exportedProperties = new DecimalFormatProperties(); 675 refreshFormatter(); 676 } 677 } 678 679 //=====================================================================================// 680 // FORMAT AND PARSE APIS // 681 //=====================================================================================// 682 683 /** 684 * {@inheritDoc} 685 */ 686 @Override 687 public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) { 688 FormattedNumber output = formatter.format(number); 689 output.populateFieldPosition(fieldPosition, result.length()); 690 output.appendTo(result); 691 return result; 692 } 693 694 /** 695 * {@inheritDoc} 696 */ 697 @Override 698 public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) { 699 FormattedNumber output = formatter.format(number); 700 output.populateFieldPosition(fieldPosition, result.length()); 701 output.appendTo(result); 702 return result; 703 } 704 705 /** 706 * {@inheritDoc} 707 */ 708 @Override 709 public StringBuffer format(BigInteger number, StringBuffer result, FieldPosition fieldPosition) { 710 FormattedNumber output = formatter.format(number); 711 output.populateFieldPosition(fieldPosition, result.length()); 712 output.appendTo(result); 713 return result; 714 } 715 716 /** 717 * {@inheritDoc} 718 */ 719 @Override 720 public StringBuffer format( 721 java.math.BigDecimal number, StringBuffer result, FieldPosition fieldPosition) { 722 FormattedNumber output = formatter.format(number); 723 output.populateFieldPosition(fieldPosition, result.length()); 724 output.appendTo(result); 725 return result; 726 } 727 728 /** 729 * {@inheritDoc} 730 */ 731 @Override 732 public StringBuffer format(BigDecimal number, StringBuffer result, FieldPosition fieldPosition) { 733 FormattedNumber output = formatter.format(number); 734 output.populateFieldPosition(fieldPosition, result.length()); 735 output.appendTo(result); 736 return result; 737 } 738 739 /** 740 * {@inheritDoc} 741 */ 742 @Override 743 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 744 if (!(obj instanceof Number)) throw new IllegalArgumentException(); 745 Number number = (Number) obj; 746 FormattedNumber output = formatter.format(number); 747 return output.getFieldIterator(); 748 } 749 750 /** 751 * {@inheritDoc} 752 */ 753 @Override 754 public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, FieldPosition pos) { 755 FormattedNumber output = formatter.format(currAmt); 756 output.populateFieldPosition(pos, toAppendTo.length()); 757 output.appendTo(toAppendTo); 758 return toAppendTo; 759 } 760 761 /** 762 * {@inheritDoc} 763 */ 764 @Override 765 public Number parse(String text, ParsePosition parsePosition) { 766 DecimalFormatProperties pprops = threadLocalProperties.get(); 767 synchronized (this) { 768 pprops.copyFrom(properties); 769 } 770 // Backwards compatibility: use currency parse mode if this is a currency instance 771 Number result = Parse.parse(text, parsePosition, pprops, symbols); 772 // Backwards compatibility: return android.icu.math.BigDecimal 773 if (result instanceof java.math.BigDecimal) { 774 result = safeConvertBigDecimal((java.math.BigDecimal) result); 775 } 776 return result; 777 } 778 779 /** 780 * {@inheritDoc} 781 */ 782 @Override 783 public CurrencyAmount parseCurrency(CharSequence text, ParsePosition parsePosition) { 784 try { 785 DecimalFormatProperties pprops = threadLocalProperties.get(); 786 synchronized (this) { 787 pprops.copyFrom(properties); 788 } 789 CurrencyAmount result = Parse.parseCurrency(text, parsePosition, pprops, symbols); 790 if (result == null) return null; 791 Number number = result.getNumber(); 792 // Backwards compatibility: return android.icu.math.BigDecimal 793 if (number instanceof java.math.BigDecimal) { 794 number = safeConvertBigDecimal((java.math.BigDecimal) number); 795 result = new CurrencyAmount(number, result.getCurrency()); 796 } 797 return result; 798 } catch (ParseException e) { 799 return null; 800 } 801 } 802 803 //=====================================================================================// 804 // GETTERS AND SETTERS // 805 //=====================================================================================// 806 807 /** 808 * Returns a copy of the decimal format symbols used by this formatter. 809 * 810 * @return desired DecimalFormatSymbols 811 * @see DecimalFormatSymbols 812 */ 813 public synchronized DecimalFormatSymbols getDecimalFormatSymbols() { 814 return (DecimalFormatSymbols) symbols.clone(); 815 } 816 817 /** 818 * Sets the decimal format symbols used by this formatter. The formatter uses a copy of the 819 * provided symbols. 820 * 821 * @param newSymbols desired DecimalFormatSymbols 822 * @see DecimalFormatSymbols 823 */ 824 public synchronized void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { 825 symbols = (DecimalFormatSymbols) newSymbols.clone(); 826 refreshFormatter(); 827 } 828 829 /** 830 * <strong>Affixes:</strong> Gets the positive prefix string currently being used to format 831 * numbers. 832 * 833 * <p>If the affix was specified via the pattern, the string returned by this method will have 834 * locale symbols substituted in place of special characters according to the LDML specification. 835 * If the affix was specified via {@link #setPositivePrefix}, the string will be returned 836 * literally. 837 * 838 * @return The string being prepended to positive numbers. 839 */ 840 public synchronized String getPositivePrefix() { 841 return formatter.format(1).getPrefix(); 842 } 843 844 /** 845 * <strong>Affixes:</strong> Sets the string to prepend to positive numbers. For example, if you 846 * set the value "#", then the number 123 will be formatted as "#123" in the locale 847 * <em>en-US</em>. 848 * 849 * <p>Using this method overrides the affix specified via the pattern, and unlike the pattern, the 850 * string given to this method will be interpreted literally WITHOUT locale symbol substitutions. 851 * 852 * @param prefix The literal string to prepend to positive numbers. 853 */ 854 public synchronized void setPositivePrefix(String prefix) { 855 if (prefix == null) { 856 throw new NullPointerException(); 857 } 858 properties.setPositivePrefix(prefix); 859 refreshFormatter(); 860 } 861 862 /** 863 * <strong>Affixes:</strong> Gets the negative prefix string currently being used to format 864 * numbers. 865 * 866 * <p>If the affix was specified via the pattern, the string returned by this method will have 867 * locale symbols substituted in place of special characters according to the LDML specification. 868 * If the affix was specified via {@link #setNegativePrefix}, the string will be returned 869 * literally. 870 * 871 * @return The string being prepended to negative numbers. 872 */ 873 public synchronized String getNegativePrefix() { 874 return formatter.format(-1).getPrefix(); 875 } 876 877 /** 878 * <strong>Affixes:</strong> Sets the string to prepend to negative numbers. For example, if you 879 * set the value "#", then the number -123 will be formatted as "#123" in the locale 880 * <em>en-US</em> (overriding the implicit default '-' in the pattern). 881 * 882 * <p>Using this method overrides the affix specified via the pattern, and unlike the pattern, the 883 * string given to this method will be interpreted literally WITHOUT locale symbol substitutions. 884 * 885 * @param prefix The literal string to prepend to negative numbers. 886 */ 887 public synchronized void setNegativePrefix(String prefix) { 888 if (prefix == null) { 889 throw new NullPointerException(); 890 } 891 properties.setNegativePrefix(prefix); 892 refreshFormatter(); 893 } 894 895 /** 896 * <strong>Affixes:</strong> Gets the positive suffix string currently being used to format 897 * numbers. 898 * 899 * <p>If the affix was specified via the pattern, the string returned by this method will have 900 * locale symbols substituted in place of special characters according to the LDML specification. 901 * If the affix was specified via {@link #setPositiveSuffix}, the string will be returned 902 * literally. 903 * 904 * @return The string being appended to positive numbers. 905 */ 906 public synchronized String getPositiveSuffix() { 907 return formatter.format(1).getSuffix(); 908 } 909 910 /** 911 * <strong>Affixes:</strong> Sets the string to append to positive numbers. For example, if you 912 * set the value "#", then the number 123 will be formatted as "123#" in the locale 913 * <em>en-US</em>. 914 * 915 * <p>Using this method overrides the affix specified via the pattern, and unlike the pattern, the 916 * string given to this method will be interpreted literally WITHOUT locale symbol substitutions. 917 * 918 * @param suffix The literal string to append to positive numbers. 919 */ 920 public synchronized void setPositiveSuffix(String suffix) { 921 if (suffix == null) { 922 throw new NullPointerException(); 923 } 924 properties.setPositiveSuffix(suffix); 925 refreshFormatter(); 926 } 927 928 /** 929 * <strong>Affixes:</strong> Gets the negative suffix string currently being used to format 930 * numbers. 931 * 932 * <p>If the affix was specified via the pattern, the string returned by this method will have 933 * locale symbols substituted in place of special characters according to the LDML specification. 934 * If the affix was specified via {@link #setNegativeSuffix}, the string will be returned 935 * literally. 936 * 937 * @return The string being appended to negative numbers. 938 */ 939 public synchronized String getNegativeSuffix() { 940 return formatter.format(-1).getSuffix(); 941 } 942 943 /** 944 * <strong>Affixes:</strong> Sets the string to append to negative numbers. For example, if you 945 * set the value "#", then the number 123 will be formatted as "123#" in the locale 946 * <em>en-US</em>. 947 * 948 * <p>Using this method overrides the affix specified via the pattern, and unlike the pattern, the 949 * string given to this method will be interpreted literally WITHOUT locale symbol substitutions. 950 * 951 * @param suffix The literal string to append to negative numbers. 952 */ 953 public synchronized void setNegativeSuffix(String suffix) { 954 if (suffix == null) { 955 throw new NullPointerException(); 956 } 957 properties.setNegativeSuffix(suffix); 958 refreshFormatter(); 959 } 960 961 /** 962 * <strong>[icu]</strong> Returns whether the sign is being shown on positive numbers. 963 * 964 * @see #setSignAlwaysShown 965 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 966 * @hide draft / provisional / internal are hidden on Android 967 */ 968 @Deprecated 969 public synchronized boolean getSignAlwaysShown() { 970 // This is not in the exported properties 971 return properties.getSignAlwaysShown(); 972 } 973 974 /** 975 * Sets whether to always shown the plus sign ('+' in <em>en</em>) on positive numbers. The rules 976 * in UTS #35 section 3.2.1 will be followed to ensure a locale-aware placement of the sign. 977 * 978 * <p>More specifically, the following strategy will be used to place the plus sign: 979 * 980 * <ol> 981 * <li><em>Patterns without a negative subpattern:</em> The locale's plus sign will be prepended 982 * to the positive prefix. 983 * <li><em>Patterns with a negative subpattern without a '-' sign (e.g., accounting):</em> The 984 * locale's plus sign will be prepended to the positive prefix, as in case 1. 985 * <li><em>Patterns with a negative subpattern that has a '-' sign:</em> The locale's plus sign 986 * will substitute the '-' in the negative subpattern. The positive subpattern will be 987 * unused. 988 * </ol> 989 * 990 * This method is designed to be used <em>instead of</em> applying a pattern containing an 991 * explicit plus sign, such as "+0;-0". The behavior when combining this method with explicit plus 992 * signs in the pattern is undefined. 993 * 994 * @param value true to always show a sign; false to hide the sign on positive numbers. 995 * @deprecated ICU 59: This API is technical preview. It may change in an upcoming release. 996 * @hide draft / provisional / internal are hidden on Android 997 */ 998 @Deprecated 999 public synchronized void setSignAlwaysShown(boolean value) { 1000 properties.setSignAlwaysShown(value); 1001 refreshFormatter(); 1002 } 1003 1004 /** 1005 * Returns the multiplier being applied to numbers before they are formatted. 1006 * 1007 * @see #setMultiplier 1008 */ 1009 public synchronized int getMultiplier() { 1010 if (properties.getMultiplier() != null) { 1011 return properties.getMultiplier().intValue(); 1012 } else { 1013 return (int) Math.pow(10, properties.getMagnitudeMultiplier()); 1014 } 1015 } 1016 1017 /** 1018 * Sets a number that will be used to multiply all numbers prior to formatting. For example, when 1019 * formatting percents, a multiplier of 100 can be used. 1020 * 1021 * <p>If a percent or permille sign is specified in the pattern, the multiplier is automatically 1022 * set to 100 or 1000, respectively. 1023 * 1024 * <p>If the number specified here is a power of 10, a more efficient code path will be used. 1025 * 1026 * @param multiplier The number by which all numbers passed to {@link #format} will be multiplied. 1027 * @throws IllegalArgumentException If the given multiplier is zero. 1028 */ 1029 public synchronized void setMultiplier(int multiplier) { 1030 if (multiplier == 0) { 1031 throw new IllegalArgumentException("Multiplier must be nonzero."); 1032 } 1033 1034 // Try to convert to a magnitude multiplier first 1035 int delta = 0; 1036 int value = multiplier; 1037 while (multiplier != 1) { 1038 delta++; 1039 int temp = value / 10; 1040 if (temp * 10 != value) { 1041 delta = -1; 1042 break; 1043 } 1044 value = temp; 1045 } 1046 if (delta != -1) { 1047 properties.setMagnitudeMultiplier(delta); 1048 } else { 1049 properties.setMultiplier(java.math.BigDecimal.valueOf(multiplier)); 1050 } 1051 refreshFormatter(); 1052 } 1053 1054 /** 1055 * <strong>[icu]</strong> Returns the increment to which numbers are being rounded. 1056 * 1057 * @see #setRoundingIncrement 1058 */ 1059 public synchronized java.math.BigDecimal getRoundingIncrement() { 1060 return exportedProperties.getRoundingIncrement(); 1061 } 1062 1063 /** 1064 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Sets an increment, or interval, to which 1065 * numbers are rounded. For example, a rounding increment of 0.05 will cause the number 1.23 to be 1066 * rounded to 1.25 in the default rounding mode. 1067 * 1068 * <p>The rounding increment can be specified via the pattern string: for example, the pattern 1069 * "#,##0.05" encodes a rounding increment of 0.05. 1070 * 1071 * <p>The rounding increment is applied <em>after</em> any multipliers might take effect; for 1072 * example, in scientific notation or when {@link #setMultiplier} is used. 1073 * 1074 * <p>See {@link #setMaximumFractionDigits} and {@link #setMaximumSignificantDigits} for two other 1075 * ways of specifying rounding strategies. 1076 * 1077 * @param increment The increment to which numbers are to be rounded. 1078 * @see #setRoundingMode 1079 * @see #setMaximumFractionDigits 1080 * @see #setMaximumSignificantDigits 1081 */ 1082 public synchronized void setRoundingIncrement(java.math.BigDecimal increment) { 1083 // Backwards compatibility: ignore rounding increment if zero, 1084 // and instead set maximum fraction digits. 1085 if (increment != null && increment.compareTo(java.math.BigDecimal.ZERO) == 0) { 1086 properties.setMaximumFractionDigits(Integer.MAX_VALUE); 1087 return; 1088 } 1089 1090 properties.setRoundingIncrement(increment); 1091 refreshFormatter(); 1092 } 1093 1094 /** 1095 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Overload of {@link 1096 * #setRoundingIncrement(java.math.BigDecimal)}. 1097 * 1098 * @param increment The increment to which numbers are to be rounded. 1099 * @see #setRoundingIncrement 1100 */ 1101 public synchronized void setRoundingIncrement(BigDecimal increment) { 1102 java.math.BigDecimal javaBigDecimal = (increment == null) ? null : increment.toBigDecimal(); 1103 setRoundingIncrement(javaBigDecimal); 1104 } 1105 1106 /** 1107 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Overload of {@link 1108 * #setRoundingIncrement(java.math.BigDecimal)}. 1109 * 1110 * @param increment The increment to which numbers are to be rounded. 1111 * @see #setRoundingIncrement 1112 */ 1113 public synchronized void setRoundingIncrement(double increment) { 1114 if (increment == 0) { 1115 setRoundingIncrement((java.math.BigDecimal) null); 1116 } else { 1117 java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(increment); 1118 setRoundingIncrement(javaBigDecimal); 1119 } 1120 } 1121 1122 /** 1123 * Returns the rounding mode being used to round numbers. 1124 * 1125 * @see #setRoundingMode 1126 */ 1127 @Override 1128 public synchronized int getRoundingMode() { 1129 RoundingMode mode = exportedProperties.getRoundingMode(); 1130 return (mode == null) ? 0 : mode.ordinal(); 1131 } 1132 1133 /** 1134 * <strong>Rounding and Digit Limits:</strong> Sets the {@link RoundingMode} used to round 1135 * numbers. The default rounding mode is HALF_EVEN, which rounds decimals to their closest whole 1136 * number, and rounds to the closest even number if at the midpoint. 1137 * 1138 * <p>For more detail on rounding modes, see <a 1139 * href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes">the ICU User 1140 * Guide</a>. 1141 * 1142 * <p>For backwards compatibility, the rounding mode is specified as an int argument, which can be 1143 * from either the constants in {@link BigDecimal} or the ordinal value of {@link RoundingMode}. 1144 * The following two calls are functionally equivalent. 1145 * 1146 * <pre> 1147 * df.setRoundingMode(BigDecimal.ROUND_CEILING); 1148 * df.setRoundingMode(RoundingMode.CEILING.ordinal()); 1149 * </pre> 1150 * 1151 * @param roundingMode The integer constant rounding mode to use when formatting numbers. 1152 */ 1153 @Override 1154 public synchronized void setRoundingMode(int roundingMode) { 1155 properties.setRoundingMode(RoundingMode.valueOf(roundingMode)); 1156 refreshFormatter(); 1157 } 1158 1159 /** 1160 * <strong>[icu]</strong> Returns the {@link java.math.MathContext} being used to round numbers. 1161 * 1162 * @see #setMathContext 1163 */ 1164 public synchronized java.math.MathContext getMathContext() { 1165 java.math.MathContext mathContext = exportedProperties.getMathContext(); 1166 assert mathContext != null; 1167 return mathContext; 1168 } 1169 1170 /** 1171 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Sets the {@link java.math.MathContext} used 1172 * to round numbers. A "math context" encodes both a rounding mode and a number of significant 1173 * digits. Most users should call {@link #setRoundingMode} and/or {@link 1174 * #setMaximumSignificantDigits} instead of this method. 1175 * 1176 * <p>When formatting, since no division is ever performed, the default MathContext is unlimited 1177 * significant digits. However, when division occurs during parsing to correct for percentages and 1178 * multipliers, a MathContext of 34 digits, the IEEE 754R Decimal128 standard, is used by default. 1179 * If you require more than 34 digits when parsing, you can set a custom MathContext using this 1180 * method. 1181 * 1182 * @param mathContext The MathContext to use when rounding numbers. 1183 * @see java.math.MathContext 1184 */ 1185 public synchronized void setMathContext(java.math.MathContext mathContext) { 1186 properties.setMathContext(mathContext); 1187 refreshFormatter(); 1188 } 1189 1190 // Remember the ICU math context form in order to be able to return it from the API. 1191 // NOTE: This value is not serialized. (should it be?) 1192 private transient int icuMathContextForm = MathContext.PLAIN; 1193 1194 /** 1195 * <strong>[icu]</strong> Returns the {@link android.icu.math.MathContext} being used to round numbers. 1196 * 1197 * @see #setMathContext 1198 */ 1199 public synchronized MathContext getMathContextICU() { 1200 java.math.MathContext mathContext = getMathContext(); 1201 return new MathContext( 1202 mathContext.getPrecision(), 1203 icuMathContextForm, 1204 false, 1205 mathContext.getRoundingMode().ordinal()); 1206 } 1207 1208 /** 1209 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Overload of {@link #setMathContext} for 1210 * {@link android.icu.math.MathContext}. 1211 * 1212 * @param mathContextICU The MathContext to use when rounding numbers. 1213 * @see #setMathContext(java.math.MathContext) 1214 */ 1215 public synchronized void setMathContextICU(MathContext mathContextICU) { 1216 icuMathContextForm = mathContextICU.getForm(); 1217 java.math.MathContext mathContext; 1218 if (mathContextICU.getLostDigits()) { 1219 // The getLostDigits() feature in ICU MathContext means "throw an ArithmeticException if 1220 // rounding causes digits to be lost". That feature is called RoundingMode.UNNECESSARY in 1221 // Java MathContext. 1222 mathContext = new java.math.MathContext(mathContextICU.getDigits(), RoundingMode.UNNECESSARY); 1223 } else { 1224 mathContext = 1225 new java.math.MathContext( 1226 mathContextICU.getDigits(), RoundingMode.valueOf(mathContextICU.getRoundingMode())); 1227 } 1228 setMathContext(mathContext); 1229 } 1230 1231 /** 1232 * Returns the effective minimum number of digits before the decimal separator. 1233 * 1234 * @see #setMinimumIntegerDigits 1235 */ 1236 @Override 1237 public synchronized int getMinimumIntegerDigits() { 1238 return exportedProperties.getMinimumIntegerDigits(); 1239 } 1240 1241 /** 1242 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digits to display before 1243 * the decimal separator. If the number has fewer than this many digits, the number is padded with 1244 * zeros. 1245 * 1246 * <p>For example, if minimum integer digits is 3, the number 12.3 will be printed as "001.23". 1247 * 1248 * <p>Minimum integer and minimum and maximum fraction digits can be specified via the pattern 1249 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fraction digits, and 3 1250 * maximum fraction digits. Note that it is not possible to specify maximium integer digits in the 1251 * pattern except in scientific notation. 1252 * 1253 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1254 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1255 * and then you set maxInt=3, then minInt will be changed to 3. 1256 * 1257 * @param value The minimum number of digits before the decimal separator. 1258 */ 1259 @Override 1260 public synchronized void setMinimumIntegerDigits(int value) { 1261 // For backwards compatibility, conflicting min/max need to keep the most recent setting. 1262 int max = properties.getMaximumIntegerDigits(); 1263 if (max >= 0 && max < value) { 1264 properties.setMaximumIntegerDigits(value); 1265 } 1266 properties.setMinimumIntegerDigits(value); 1267 refreshFormatter(); 1268 } 1269 1270 /** 1271 * Returns the effective maximum number of digits before the decimal separator. 1272 * 1273 * @see #setMaximumIntegerDigits 1274 */ 1275 @Override 1276 public synchronized int getMaximumIntegerDigits() { 1277 return exportedProperties.getMaximumIntegerDigits(); 1278 } 1279 1280 /** 1281 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digits to display before 1282 * the decimal separator. If the number has more than this many digits, the number is truncated. 1283 * 1284 * <p>For example, if maximum integer digits is 3, the number 12345 will be printed as "345". 1285 * 1286 * <p>Minimum integer and minimum and maximum fraction digits can be specified via the pattern 1287 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fraction digits, and 3 1288 * maximum fraction digits. Note that it is not possible to specify maximium integer digits in the 1289 * pattern except in scientific notation. 1290 * 1291 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1292 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1293 * and then you set maxInt=3, then minInt will be changed to 3. 1294 * 1295 * @param value The maximum number of digits before the decimal separator. 1296 */ 1297 @Override 1298 public synchronized void setMaximumIntegerDigits(int value) { 1299 int min = properties.getMinimumIntegerDigits(); 1300 if (min >= 0 && min > value) { 1301 properties.setMinimumIntegerDigits(value); 1302 } 1303 properties.setMaximumIntegerDigits(value); 1304 refreshFormatter(); 1305 } 1306 1307 /** 1308 * Returns the effective minimum number of integer digits after the decimal separator. 1309 * 1310 * @see #setMaximumIntegerDigits 1311 */ 1312 @Override 1313 public synchronized int getMinimumFractionDigits() { 1314 return exportedProperties.getMinimumFractionDigits(); 1315 } 1316 1317 /** 1318 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digits to display after 1319 * the decimal separator. If the number has fewer than this many digits, the number is padded with 1320 * zeros. 1321 * 1322 * <p>For example, if minimum fraction digits is 2, the number 123.4 will be printed as "123.40". 1323 * 1324 * <p>Minimum integer and minimum and maximum fraction digits can be specified via the pattern 1325 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fraction digits, and 3 1326 * maximum fraction digits. Note that it is not possible to specify maximium integer digits in the 1327 * pattern except in scientific notation. 1328 * 1329 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1330 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1331 * and then you set maxInt=3, then minInt will be changed to 3. 1332 * 1333 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumSignificantDigits} for two other 1334 * ways of specifying rounding strategies. 1335 * 1336 * @param value The minimum number of integer digits after the decimal separator. 1337 * @see #setRoundingMode 1338 * @see #setRoundingIncrement 1339 * @see #setMaximumSignificantDigits 1340 */ 1341 @Override 1342 public synchronized void setMinimumFractionDigits(int value) { 1343 int max = properties.getMaximumFractionDigits(); 1344 if (max >= 0 && max < value) { 1345 properties.setMaximumFractionDigits(value); 1346 } 1347 properties.setMinimumFractionDigits(value); 1348 refreshFormatter(); 1349 } 1350 1351 /** 1352 * Returns the effective maximum number of integer digits after the decimal separator. 1353 * 1354 * @see #setMaximumIntegerDigits 1355 */ 1356 @Override 1357 public synchronized int getMaximumFractionDigits() { 1358 return exportedProperties.getMaximumFractionDigits(); 1359 } 1360 1361 /** 1362 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digits to display after 1363 * the decimal separator. If the number has more than this many digits, the number is rounded 1364 * according to the rounding mode. 1365 * 1366 * <p>For example, if maximum fraction digits is 2, the number 123.456 will be printed as 1367 * "123.46". 1368 * 1369 * <p>Minimum integer and minimum and maximum fraction digits can be specified via the pattern 1370 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fraction digits, and 3 1371 * maximum fraction digits. Note that it is not possible to specify maximium integer digits in the 1372 * pattern except in scientific notation. 1373 * 1374 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1375 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1376 * and then you set maxInt=3, then minInt will be changed to 3. 1377 * 1378 * @param value The maximum number of integer digits after the decimal separator. 1379 * @see #setRoundingMode 1380 */ 1381 @Override 1382 public synchronized void setMaximumFractionDigits(int value) { 1383 int min = properties.getMinimumFractionDigits(); 1384 if (min >= 0 && min > value) { 1385 properties.setMinimumFractionDigits(value); 1386 } 1387 properties.setMaximumFractionDigits(value); 1388 refreshFormatter(); 1389 } 1390 1391 /** 1392 * <strong>[icu]</strong> Returns whether significant digits are being used in rounding. 1393 * 1394 * @see #setSignificantDigitsUsed 1395 */ 1396 public synchronized boolean areSignificantDigitsUsed() { 1397 return properties.getMinimumSignificantDigits() != -1 1398 || properties.getMaximumSignificantDigits() != -1; 1399 } 1400 1401 /** 1402 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Sets whether significant digits are to be 1403 * used in rounding. 1404 * 1405 * <p>Calling <code>df.setSignificantDigitsUsed(true)</code> is functionally equivalent to: 1406 * 1407 * <pre> 1408 * df.setMinimumSignificantDigits(1); 1409 * df.setMaximumSignificantDigits(6); 1410 * </pre> 1411 * 1412 * @param useSignificantDigits true to enable significant digit rounding; false to disable it. 1413 */ 1414 public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits) { 1415 if (useSignificantDigits) { 1416 // These are the default values from the old implementation. 1417 properties.setMinimumSignificantDigits(1); 1418 properties.setMaximumSignificantDigits(6); 1419 } else { 1420 properties.setMinimumSignificantDigits(-1); 1421 properties.setMaximumSignificantDigits(-1); 1422 } 1423 refreshFormatter(); 1424 } 1425 1426 /** 1427 * <strong>[icu]</strong> Returns the effective minimum number of significant digits displayed. 1428 * 1429 * @see #setMinimumSignificantDigits 1430 */ 1431 public synchronized int getMinimumSignificantDigits() { 1432 return exportedProperties.getMinimumSignificantDigits(); 1433 } 1434 1435 /** 1436 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Sets the minimum number of significant 1437 * digits to be displayed. If the number of significant digits is less than this value, the number 1438 * will be padded with zeros as necessary. 1439 * 1440 * <p>For example, if minimum significant digits is 3 and the number is 1.2, the number will be 1441 * printed as "1.20". 1442 * 1443 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1444 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1445 * and then you set maxInt=3, then minInt will be changed to 3. 1446 * 1447 * @param value The minimum number of significant digits to display. 1448 */ 1449 public synchronized void setMinimumSignificantDigits(int value) { 1450 int max = properties.getMaximumSignificantDigits(); 1451 if (max >= 0 && max < value) { 1452 properties.setMaximumSignificantDigits(value); 1453 } 1454 properties.setMinimumSignificantDigits(value); 1455 refreshFormatter(); 1456 } 1457 1458 /** 1459 * <strong>[icu]</strong> Returns the effective maximum number of significant digits displayed. 1460 * 1461 * @see #setMaximumSignificantDigits 1462 */ 1463 public synchronized int getMaximumSignificantDigits() { 1464 return exportedProperties.getMaximumSignificantDigits(); 1465 } 1466 1467 /** 1468 * <strong>[icu]</strong> <strong>Rounding and Digit Limits:</strong> Sets the maximum number of significant 1469 * digits to be displayed. If the number of significant digits in the number exceeds this value, 1470 * the number will be rounded according to the current rounding mode. 1471 * 1472 * <p>For example, if maximum significant digits is 3 and the number is 12345, the number will be 1473 * printed as "12300". 1474 * 1475 * <p>If minimum and maximum integer, fraction, or significant digits conflict with each other, 1476 * the most recently specified value is used. For example, if there is a formatter with minInt=5, 1477 * and then you set maxInt=3, then minInt will be changed to 3. 1478 * 1479 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumFractionDigits} for two other ways 1480 * of specifying rounding strategies. 1481 * 1482 * @param value The maximum number of significant digits to display. 1483 * @see #setRoundingMode 1484 * @see #setRoundingIncrement 1485 * @see #setMaximumFractionDigits 1486 */ 1487 public synchronized void setMaximumSignificantDigits(int value) { 1488 int min = properties.getMinimumSignificantDigits(); 1489 if (min >= 0 && min > value) { 1490 properties.setMinimumSignificantDigits(value); 1491 } 1492 properties.setMaximumSignificantDigits(value); 1493 refreshFormatter(); 1494 } 1495 1496 /** 1497 * Returns the minimum number of characters in formatted output. 1498 * 1499 * @see #setFormatWidth 1500 */ 1501 public synchronized int getFormatWidth() { 1502 return properties.getFormatWidth(); 1503 } 1504 1505 /** 1506 * <strong>Padding:</strong> Sets the minimum width of the string output by the formatting 1507 * pipeline. For example, if padding is enabled and paddingWidth is set to 6, formatting the 1508 * number "3.14159" with the pattern "0.00" will result in "3.14" if '' is your padding string. 1509 * 1510 * <p>If the number is longer than your padding width, the number will display as if no padding 1511 * width had been specified, which may result in strings longer than the padding width. 1512 * 1513 * <p>Padding can be specified in the pattern string using the '*' symbol. For example, the format 1514 * "*x######0" has a format width of 7 and a pad character of 'x'. 1515 * 1516 * <p>Padding is currently counted in UTF-16 code units; see <a 1517 * href="http://bugs.icu-project.org/trac/ticket/13034">ticket #13034</a> for more information. 1518 * 1519 * @param width The minimum number of characters in the output. 1520 * @see #setPadCharacter 1521 * @see #setPadPosition 1522 */ 1523 public synchronized void setFormatWidth(int width) { 1524 properties.setFormatWidth(width); 1525 refreshFormatter(); 1526 } 1527 1528 /** 1529 * <strong>[icu]</strong> Returns the character used for padding. 1530 * 1531 * @see #setPadCharacter 1532 */ 1533 public synchronized char getPadCharacter() { 1534 CharSequence paddingString = properties.getPadString(); 1535 if (paddingString == null) { 1536 return '.'; // TODO: Is this the correct behavior? 1537 } else { 1538 return paddingString.charAt(0); 1539 } 1540 } 1541 1542 /** 1543 * <strong>[icu]</strong> <strong>Padding:</strong> Sets the character used to pad numbers that are narrower than 1544 * the width specified in {@link #setFormatWidth}. 1545 * 1546 * <p>In the pattern string, the padding character is the token that follows '*' before or after 1547 * the prefix or suffix. 1548 * 1549 * @param padChar The character used for padding. 1550 * @see #setFormatWidth 1551 */ 1552 public synchronized void setPadCharacter(char padChar) { 1553 properties.setPadString(Character.toString(padChar)); 1554 refreshFormatter(); 1555 } 1556 1557 /** 1558 * <strong>[icu]</strong> Returns the position used for padding. 1559 * 1560 * @see #setPadPosition 1561 */ 1562 public synchronized int getPadPosition() { 1563 PadPosition loc = properties.getPadPosition(); 1564 return (loc == null) ? PAD_BEFORE_PREFIX : loc.toOld(); 1565 } 1566 1567 /** 1568 * <strong>[icu]</strong> <strong>Padding:</strong> Sets the position where to insert the pad character when 1569 * narrower than the width specified in {@link #setFormatWidth}. For example, consider the pattern 1570 * "P123S" with padding width 8 and padding char "*". The four positions are: 1571 * 1572 * <ul> 1573 * <li>{@link DecimalFormat#PAD_BEFORE_PREFIX} "***P123S" 1574 * <li>{@link DecimalFormat#PAD_AFTER_PREFIX} "P***123S" 1575 * <li>{@link DecimalFormat#PAD_BEFORE_SUFFIX} "P123***S" 1576 * <li>{@link DecimalFormat#PAD_AFTER_SUFFIX} "P123S***" 1577 * </ul> 1578 * 1579 * @param padPos The position used for padding. 1580 * @see #setFormatWidth 1581 */ 1582 public synchronized void setPadPosition(int padPos) { 1583 properties.setPadPosition(PadPosition.fromOld(padPos)); 1584 refreshFormatter(); 1585 } 1586 1587 /** 1588 * <strong>[icu]</strong> Returns whether scientific (exponential) notation is enabled on this formatter. 1589 * 1590 * @see #setScientificNotation 1591 */ 1592 public synchronized boolean isScientificNotation() { 1593 return properties.getMinimumExponentDigits() != -1; 1594 } 1595 1596 /** 1597 * <strong>[icu]</strong> <strong>Scientific Notation:</strong> Sets whether this formatter should print in 1598 * scientific (exponential) notation. For example, if scientific notation is enabled, the number 1599 * 123000 will be printed as "1.23E5" in locale <em>en-US</em>. A locale-specific symbol is used 1600 * as the exponent separator. 1601 * 1602 * <p>Calling <code>df.setScientificNotation(true)</code> is functionally equivalent to calling 1603 * <code>df.setMinimumExponentDigits(1)</code>. 1604 * 1605 * @param useScientific true to enable scientific notation; false to disable it. 1606 * @see #setMinimumExponentDigits 1607 */ 1608 public synchronized void setScientificNotation(boolean useScientific) { 1609 if (useScientific) { 1610 properties.setMinimumExponentDigits(1); 1611 } else { 1612 properties.setMinimumExponentDigits(-1); 1613 } 1614 refreshFormatter(); 1615 } 1616 1617 /** 1618 * <strong>[icu]</strong> Returns the minimum number of digits printed in the exponent in scientific notation. 1619 * 1620 * @see #setMinimumExponentDigits 1621 */ 1622 public synchronized byte getMinimumExponentDigits() { 1623 return (byte) properties.getMinimumExponentDigits(); 1624 } 1625 1626 /** 1627 * <strong>[icu]</strong> <strong>Scientific Notation:</strong> Sets the minimum number of digits to be printed in 1628 * the exponent. For example, if minimum exponent digits is 3, the number 123000 will be printed 1629 * as "1.23E005". 1630 * 1631 * <p>This setting corresponds to the number of zeros after the 'E' in a pattern string such as 1632 * "0.00E000". 1633 * 1634 * @param minExpDig The minimum number of digits in the exponent. 1635 */ 1636 public synchronized void setMinimumExponentDigits(byte minExpDig) { 1637 properties.setMinimumExponentDigits(minExpDig); 1638 refreshFormatter(); 1639 } 1640 1641 /** 1642 * <strong>[icu]</strong> Returns whether the sign (plus or minus) is always printed in scientific notation. 1643 * 1644 * @see #setExponentSignAlwaysShown 1645 */ 1646 public synchronized boolean isExponentSignAlwaysShown() { 1647 return properties.getExponentSignAlwaysShown(); 1648 } 1649 1650 /** 1651 * <strong>[icu]</strong> <strong>Scientific Notation:</strong> Sets whether the sign (plus or minus) is always to 1652 * be shown in the exponent in scientific notation. For example, if this setting is enabled, the 1653 * number 123000 will be printed as "1.23E+5" in locale <em>en-US</em>. The number 0.0000123 will 1654 * always be printed as "1.23E-5" in locale <em>en-US</em> whether or not this setting is enabled. 1655 * 1656 * <p>This setting corresponds to the '+' in a pattern such as "0.00E+0". 1657 * 1658 * @param expSignAlways true to always shown the sign in the exponent; false to show it for 1659 * negatives but not positives. 1660 */ 1661 public synchronized void setExponentSignAlwaysShown(boolean expSignAlways) { 1662 properties.setExponentSignAlwaysShown(expSignAlways); 1663 refreshFormatter(); 1664 } 1665 1666 /** 1667 * Returns whether or not grouping separators are being printed in the output. 1668 * 1669 * @see #setGroupingUsed 1670 */ 1671 @Override 1672 public synchronized boolean isGroupingUsed() { 1673 return properties.getGroupingSize() > 0 || properties.getSecondaryGroupingSize() > 0; 1674 } 1675 1676 /** 1677 * <strong>Grouping:</strong> Sets whether grouping is to be used when formatting numbers. 1678 * Grouping means whether the thousands, millions, billions, and larger powers of ten should be 1679 * separated by a grouping separator (a comma in <em>en-US</em>). 1680 * 1681 * <p>For example, if grouping is enabled, 12345 will be printed as "12,345" in <em>en-US</em>. If 1682 * grouping were disabled, it would instead be printed as simply "12345". 1683 * 1684 * <p>Calling <code>df.setGroupingUsed(true)</code> is functionally equivalent to setting grouping 1685 * size to 3, as in <code>df.setGroupingSize(3)</code>. 1686 * 1687 * @param enabled true to enable grouping separators; false to disable them. 1688 * @see #setGroupingSize 1689 * @see #setSecondaryGroupingSize 1690 */ 1691 @Override 1692 public synchronized void setGroupingUsed(boolean enabled) { 1693 if (enabled) { 1694 // Set to a reasonable default value 1695 properties.setGroupingSize(3); 1696 } else { 1697 properties.setGroupingSize(0); 1698 properties.setSecondaryGroupingSize(0); 1699 } 1700 refreshFormatter(); 1701 } 1702 1703 /** 1704 * Returns the primary grouping size in use. 1705 * 1706 * @see #setGroupingSize 1707 */ 1708 public synchronized int getGroupingSize() { 1709 return properties.getGroupingSize(); 1710 } 1711 1712 /** 1713 * <strong>Grouping:</strong> Sets the primary grouping size (distance between grouping 1714 * separators) used when formatting large numbers. For most locales, this defaults to 3: the 1715 * number of digits between the ones and thousands place, between thousands and millions, and so 1716 * forth. 1717 * 1718 * <p>For example, with a grouping size of 3, the number 1234567 will be formatted as "1,234,567". 1719 * 1720 * <p>Grouping size can also be specified in the pattern: for example, "#,##0" corresponds to a 1721 * grouping size of 3. 1722 * 1723 * @param width The grouping size to use. 1724 * @see #setSecondaryGroupingSize 1725 */ 1726 public synchronized void setGroupingSize(int width) { 1727 properties.setGroupingSize(width); 1728 refreshFormatter(); 1729 } 1730 1731 /** 1732 * <strong>[icu]</strong> Returns the secondary grouping size in use. 1733 * 1734 * @see #setSecondaryGroupingSize 1735 */ 1736 public synchronized int getSecondaryGroupingSize() { 1737 int grouping1 = properties.getGroupingSize(); 1738 int grouping2 = properties.getSecondaryGroupingSize(); 1739 if (grouping1 == grouping2 || grouping2 < 0) { 1740 return 0; 1741 } 1742 return properties.getSecondaryGroupingSize(); 1743 } 1744 1745 /** 1746 * <strong>[icu]</strong> <strong>Grouping:</strong> Sets the secondary grouping size (distance between grouping 1747 * separators after the first separator) used when formatting large numbers. In many south Asian 1748 * locales, this is set to 2. 1749 * 1750 * <p>For example, with primary grouping size 3 and secondary grouping size 2, the number 1234567 1751 * will be formatted as "12,34,567". 1752 * 1753 * <p>Grouping size can also be specified in the pattern: for example, "#,##,##0" corresponds to a 1754 * primary grouping size of 3 and a secondary grouping size of 2. 1755 * 1756 * @param width The secondary grouping size to use. 1757 * @see #setGroupingSize 1758 */ 1759 public synchronized void setSecondaryGroupingSize(int width) { 1760 properties.setSecondaryGroupingSize(width); 1761 refreshFormatter(); 1762 } 1763 1764 /** 1765 * <strong>[icu]</strong> Returns the minimum number of digits before grouping is triggered. 1766 * 1767 * @see #setMinimumGroupingDigits 1768 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 1769 * @hide draft / provisional / internal are hidden on Android 1770 */ 1771 @Deprecated 1772 public synchronized int getMinimumGroupingDigits() { 1773 // Only 1 and 2 are supported right now. 1774 if (properties.getMinimumGroupingDigits() == 2) { 1775 return 2; 1776 } else { 1777 return 1; 1778 } 1779 } 1780 1781 /** 1782 * <strong>[icu]</strong> Sets the minimum number of digits that must be before the first grouping separator in 1783 * order for the grouping separator to be printed. For example, if minimum grouping digits is set 1784 * to 2, in <em>en-US</em>, 1234 will be printed as "1234" and 12345 will be printed as "12,345". 1785 * 1786 * @param number The minimum number of digits before grouping is triggered. 1787 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 1788 * @hide draft / provisional / internal are hidden on Android 1789 */ 1790 @Deprecated 1791 public synchronized void setMinimumGroupingDigits(int number) { 1792 properties.setMinimumGroupingDigits(number); 1793 refreshFormatter(); 1794 } 1795 1796 /** 1797 * Returns whether the decimal separator is shown on integers. 1798 * 1799 * @see #setDecimalSeparatorAlwaysShown 1800 */ 1801 public synchronized boolean isDecimalSeparatorAlwaysShown() { 1802 return properties.getDecimalSeparatorAlwaysShown(); 1803 } 1804 1805 /** 1806 * <strong>Separators:</strong> Sets whether the decimal separator (a period in <em>en-US</em>) is 1807 * shown on integers. For example, if this setting is turned on, formatting 123 will result in 1808 * "123." with the decimal separator. 1809 * 1810 * <p>This setting can be specified in the pattern for integer formats: "#,##0." is an example. 1811 * 1812 * @param value true to always show the decimal separator; false to show it only when there is a 1813 * fraction part of the number. 1814 */ 1815 public synchronized void setDecimalSeparatorAlwaysShown(boolean value) { 1816 properties.setDecimalSeparatorAlwaysShown(value); 1817 refreshFormatter(); 1818 } 1819 1820 /** 1821 * Returns the user-specified currency. May be null. 1822 * 1823 * @see #setCurrency 1824 * @see DecimalFormatSymbols#getCurrency 1825 */ 1826 @Override 1827 public synchronized Currency getCurrency() { 1828 return properties.getCurrency(); 1829 } 1830 1831 /** 1832 * Sets the currency to be used when formatting numbers. The effect is twofold: 1833 * 1834 * <ol> 1835 * <li>Substitutions for currency symbols in the pattern string will use this currency 1836 * <li>The rounding mode will obey the rules for this currency (see {@link #setCurrencyUsage}) 1837 * </ol> 1838 * 1839 * <strong>Important:</strong> Displaying the currency in the output requires that the patter 1840 * associated with this formatter contains a currency symbol ''. This will be the case if the 1841 * instance was created via {@link #getCurrencyInstance} or one of its friends. 1842 * 1843 * @param currency The currency to use. 1844 */ 1845 @Override 1846 public synchronized void setCurrency(Currency currency) { 1847 properties.setCurrency(currency); 1848 // Backwards compatibility: also set the currency in the DecimalFormatSymbols 1849 if (currency != null) { 1850 symbols.setCurrency(currency); 1851 String symbol = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null); 1852 symbols.setCurrencySymbol(symbol); 1853 } 1854 refreshFormatter(); 1855 } 1856 1857 /** 1858 * <strong>[icu]</strong> Returns the strategy for rounding currency amounts. 1859 * 1860 * @see #setCurrencyUsage 1861 */ 1862 public synchronized CurrencyUsage getCurrencyUsage() { 1863 // CurrencyUsage is not exported, so we have to get it from the input property bag. 1864 // TODO: Should we export CurrencyUsage instead? 1865 CurrencyUsage usage = properties.getCurrencyUsage(); 1866 if (usage == null) { 1867 usage = CurrencyUsage.STANDARD; 1868 } 1869 return usage; 1870 } 1871 1872 /** 1873 * <strong>[icu]</strong> Sets the currency-dependent strategy to use when rounding numbers. There are two 1874 * strategies: 1875 * 1876 * <ul> 1877 * <li>STANDARD: When the amount displayed is intended for banking statements or electronic 1878 * transfer. 1879 * <li>CASH: When the amount displayed is intended to be representable in physical currency, 1880 * like at a cash register. 1881 * </ul> 1882 * 1883 * CASH mode is relevant in currencies that do not have tender down to the penny. For more 1884 * information on the two rounding strategies, see <a 1885 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Supplemental_Currency_Data">UTS 1886 * #35</a>. If omitted, the strategy defaults to STANDARD. To override currency rounding 1887 * altogether, use {@link #setMinimumFractionDigits} and {@link #setMaximumFractionDigits} or 1888 * {@link #setRoundingIncrement}. 1889 * 1890 * @param usage The strategy to use when rounding in the current currency. 1891 */ 1892 public synchronized void setCurrencyUsage(CurrencyUsage usage) { 1893 properties.setCurrencyUsage(usage); 1894 refreshFormatter(); 1895 } 1896 1897 /** 1898 * <strong>[icu]</strong> Returns the current instance of CurrencyPluralInfo. 1899 * 1900 * @see #setCurrencyPluralInfo 1901 */ 1902 public synchronized CurrencyPluralInfo getCurrencyPluralInfo() { 1903 // CurrencyPluralInfo also is not exported. 1904 return properties.getCurrencyPluralInfo(); 1905 } 1906 1907 /** 1908 * <strong>[icu]</strong> Sets a custom instance of CurrencyPluralInfo. CurrencyPluralInfo generates pattern 1909 * strings for printing currency long names. 1910 * 1911 * <p><strong>Most users should not call this method directly.</strong> You should instead create 1912 * your formatter via <code>NumberFormat.getInstance(NumberFormat.PLURALCURRENCYSTYLE)</code>. 1913 * 1914 * @param newInfo The CurrencyPluralInfo to use when printing currency long names. 1915 */ 1916 public synchronized void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { 1917 properties.setCurrencyPluralInfo(newInfo); 1918 refreshFormatter(); 1919 } 1920 1921 /** 1922 * Returns whether {@link #parse} will always return a BigDecimal. 1923 * 1924 * @see #setParseBigDecimal 1925 */ 1926 public synchronized boolean isParseBigDecimal() { 1927 return properties.getParseToBigDecimal(); 1928 } 1929 1930 /** 1931 * Whether to make {@link #parse} prefer returning a {@link android.icu.math.BigDecimal} when 1932 * possible. For strings corresponding to return values of Infinity, -Infinity, NaN, and -0.0, a 1933 * Double will be returned even if ParseBigDecimal is enabled. 1934 * 1935 * @param value true to cause {@link #parse} to prefer BigDecimal; false to let {@link #parse} 1936 * return additional data types like Long or BigInteger. 1937 */ 1938 public synchronized void setParseBigDecimal(boolean value) { 1939 properties.setParseToBigDecimal(value); 1940 // refreshFormatter() not needed 1941 } 1942 1943 /** 1944 * Always returns 1000, the default prior to ICU 59. 1945 * 1946 * @deprecated Setting max parse digits has no effect since ICU4J 59. 1947 */ 1948 @Deprecated 1949 public int getParseMaxDigits() { 1950 return 1000; 1951 } 1952 1953 /** 1954 * @param maxDigits Prior to ICU 59, the maximum number of digits in the output number after 1955 * exponential notation is applied. 1956 * @deprecated Setting max parse digits has no effect since ICU4J 59. 1957 */ 1958 @Deprecated 1959 public void setParseMaxDigits(int maxDigits) {} 1960 1961 /** 1962 * {@inheritDoc} 1963 */ 1964 @Override 1965 public synchronized boolean isParseStrict() { 1966 return properties.getParseMode() == Parse.ParseMode.STRICT; 1967 } 1968 1969 /** 1970 * {@inheritDoc} 1971 */ 1972 @Override 1973 public synchronized void setParseStrict(boolean parseStrict) { 1974 Parse.ParseMode mode = parseStrict ? Parse.ParseMode.STRICT : Parse.ParseMode.LENIENT; 1975 properties.setParseMode(mode); 1976 // refreshFormatter() not needed 1977 } 1978 1979 /** 1980 * {@inheritDoc} 1981 * 1982 * @see #setParseIntegerOnly 1983 */ 1984 @Override 1985 public synchronized boolean isParseIntegerOnly() { 1986 return properties.getParseIntegerOnly(); 1987 } 1988 1989 /** 1990 * <strong>Parsing:</strong> {@inheritDoc} 1991 * 1992 * <p>This is functionally equivalent to calling {@link #setDecimalPatternMatchRequired} and a 1993 * pattern without a decimal point. 1994 * 1995 * @param parseIntegerOnly true to ignore fractional parts of numbers when parsing; false to 1996 * consume fractional parts. 1997 */ 1998 @Override 1999 public synchronized void setParseIntegerOnly(boolean parseIntegerOnly) { 2000 properties.setParseIntegerOnly(parseIntegerOnly); 2001 // refreshFormatter() not needed 2002 } 2003 2004 /** 2005 * <strong>[icu]</strong> Returns whether the presence of a decimal point must match the pattern. 2006 * 2007 * @see #setDecimalPatternMatchRequired 2008 */ 2009 public synchronized boolean isDecimalPatternMatchRequired() { 2010 return properties.getDecimalPatternMatchRequired(); 2011 } 2012 2013 /** 2014 * <strong>[icu]</strong> <strong>Parsing:</strong> This method is used to either <em>require</em> or 2015 * <em>forbid</em> the presence of a decimal point in the string being parsed (disabled by 2016 * default). This feature was designed to be an extra layer of strictness on top of strict 2017 * parsing, although it can be used in either lenient mode or strict mode. 2018 * 2019 * <p>To <em>require</em> a decimal point, call this method in combination with either a pattern 2020 * containing a decimal point or with {@link #setDecimalSeparatorAlwaysShown}. 2021 * 2022 * <pre> 2023 * // Require a decimal point in the string being parsed: 2024 * df.applyPattern("#."); 2025 * df.setDecimalPatternMatchRequired(true); 2026 * 2027 * // Alternatively: 2028 * df.setDecimalSeparatorAlwaysShown(true); 2029 * df.setDecimalPatternMatchRequired(true); 2030 * </pre> 2031 * 2032 * To <em>forbid</em> a decimal point, call this method in combination with a pattern containing 2033 * no decimal point. Alternatively, use {@link #setParseIntegerOnly} for the same behavior without 2034 * depending on the contents of the pattern string. 2035 * 2036 * <pre> 2037 * // Forbid a decimal point in the string being parsed: 2038 * df.applyPattern("#"); 2039 * df.setDecimalPatternMatchRequired(true); 2040 * </pre> 2041 * 2042 * @param value true to either require or forbid the decimal point according to the pattern; false 2043 * to disable this feature. 2044 * @see #setParseIntegerOnly 2045 */ 2046 public synchronized void setDecimalPatternMatchRequired(boolean value) { 2047 properties.setDecimalPatternMatchRequired(value); 2048 refreshFormatter(); 2049 } 2050 2051 /** 2052 * <strong>[icu]</strong> Returns whether to ignore exponents when parsing. 2053 * 2054 * @see #setParseNoExponent 2055 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 2056 * @hide draft / provisional / internal are hidden on Android 2057 */ 2058 @Deprecated 2059 public synchronized boolean getParseNoExponent() { 2060 return properties.getParseNoExponent(); 2061 } 2062 2063 /** 2064 * <strong>[icu]</strong> Specifies whether to stop parsing when an exponent separator is encountered. For 2065 * example, parses "123E4" to 123 (with parse position 3) instead of 1230000 (with parse position 2066 * 5). 2067 * 2068 * @param value true to prevent exponents from being parsed; false to allow them to be parsed. 2069 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 2070 * @hide draft / provisional / internal are hidden on Android 2071 */ 2072 @Deprecated 2073 public synchronized void setParseNoExponent(boolean value) { 2074 properties.setParseNoExponent(value); 2075 refreshFormatter(); 2076 } 2077 2078 /** 2079 * <strong>[icu]</strong> Returns whether to force case (uppercase/lowercase) to match when parsing. 2080 * 2081 * @see #setParseNoExponent 2082 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 2083 * @hide draft / provisional / internal are hidden on Android 2084 */ 2085 @Deprecated 2086 public synchronized boolean getParseCaseSensitive() { 2087 return properties.getParseCaseSensitive(); 2088 } 2089 2090 /** 2091 * <strong>[icu]</strong> Specifies whether parsing should require cases to match in affixes, exponent separators, 2092 * and currency codes. Case mapping is performed for each code point using {@link 2093 * UCharacter#foldCase}. 2094 * 2095 * @param value true to force case (uppercase/lowercase) to match when parsing; false to ignore 2096 * case and perform case folding. 2097 * @deprecated ICU 59: This API is a technical preview. It may change in an upcoming release. 2098 * @hide draft / provisional / internal are hidden on Android 2099 */ 2100 @Deprecated 2101 public synchronized void setParseCaseSensitive(boolean value) { 2102 properties.setParseCaseSensitive(value); 2103 refreshFormatter(); 2104 } 2105 2106 // TODO(sffc): Uncomment for ICU 60 API proposal. 2107 // 2108 // /** 2109 // * {@icu} Returns the strategy used for choosing between grouping and decimal separators when 2110 // * parsing. 2111 // * 2112 // * @see #setParseGroupingMode 2113 // * @category Parsing 2114 // */ 2115 // public synchronized GroupingMode getParseGroupingMode() { 2116 // return properties.getParseGroupingMode(); 2117 // } 2118 // 2119 // /** 2120 // * {@icu} Sets the strategy used during parsing when a code point needs to be interpreted as 2121 // * either a decimal separator or a grouping separator. 2122 // * 2123 // * <p>The comma, period, space, and apostrophe have different meanings in different locales. For 2124 // * example, in <em>en-US</em> and most American locales, the period is used as a decimal 2125 // * separator, but in <em>es-PY</em> and most European locales, it is used as a grouping separator. 2126 // * 2127 // * Suppose you are in <em>fr-FR</em> the parser encounters the string "1.234". In <em>fr-FR</em>, 2128 // * the grouping is a space and the decimal is a comma. The <em>grouping mode</em> is a mechanism 2129 // * to let you specify whether to accept the string as 1234 (GroupingMode.DEFAULT) or whether to reject it since the separators 2130 // * don't match (GroupingMode.RESTRICTED). 2131 // * 2132 // * When resolving grouping separators, it is the <em>equivalence class</em> of separators that is considered. 2133 // * For example, a period is seen as equal to a fixed set of other period-like characters. 2134 // * 2135 // * @param groupingMode The strategy to use; either DEFAULT or RESTRICTED. 2136 // * @category Parsing 2137 // */ 2138 // public synchronized void setParseGroupingMode(GroupingMode groupingMode) { 2139 // properties.setParseGroupingMode(groupingMode); 2140 // refreshFormatter(); 2141 // } 2142 2143 //=====================================================================================// 2144 // UTILITIES // 2145 //=====================================================================================// 2146 2147 /** 2148 * Tests for equality between this formatter and another formatter. 2149 * 2150 * <p>If two DecimalFormat instances are equal, then they will always produce the same output. 2151 * However, the reverse is not necessarily true: if two DecimalFormat instances always produce the 2152 * same output, they are not necessarily equal. 2153 */ 2154 @Override 2155 public synchronized boolean equals(Object obj) { 2156 if (obj == null) return false; 2157 if (obj == this) return true; 2158 if (!(obj instanceof DecimalFormat)) return false; 2159 DecimalFormat other = (DecimalFormat) obj; 2160 return properties.equals(other.properties) && symbols.equals(other.symbols); 2161 } 2162 2163 /** 2164 * {@inheritDoc} 2165 */ 2166 @Override 2167 public synchronized int hashCode() { 2168 return properties.hashCode() ^ symbols.hashCode(); 2169 } 2170 2171 /** 2172 * Returns the default value of toString() with extra DecimalFormat-specific information appended 2173 * to the end of the string. This extra information is intended for debugging purposes, and the 2174 * format is not guaranteed to be stable. 2175 */ 2176 @Override 2177 public String toString() { 2178 StringBuilder result = new StringBuilder(); 2179 result.append(getClass().getName()); 2180 result.append("@"); 2181 result.append(Integer.toHexString(hashCode())); 2182 result.append(" { symbols@"); 2183 result.append(Integer.toHexString(symbols.hashCode())); 2184 synchronized (this) { 2185 properties.toStringBare(result); 2186 } 2187 result.append(" }"); 2188 return result.toString(); 2189 } 2190 2191 /** 2192 * Serializes this formatter object to a decimal format pattern string. The result of this method 2193 * is guaranteed to be <em>functionally</em> equivalent to the pattern string used to create this 2194 * instance after incorporating values from the setter methods. 2195 * 2196 * <p>For more information on decimal format pattern strings, see <a 2197 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns">UTS #35</a>. 2198 * 2199 * <p><strong>Important:</strong> Not all properties are capable of being encoded in a pattern 2200 * string. See a list of properties in {@link #applyPattern}. 2201 * 2202 * @return A decimal format pattern string. 2203 */ 2204 public synchronized String toPattern() { 2205 // Pull some properties from exportedProperties and others from properties 2206 // to keep affix patterns intact. In particular, pull rounding properties 2207 // so that CurrencyUsage is reflected properly. 2208 // TODO: Consider putting this logic in PatternString.java instead. 2209 DecimalFormatProperties tprops = threadLocalProperties.get().copyFrom(properties); 2210 if (useCurrency(properties)) { 2211 tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigits()); 2212 tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigits()); 2213 tprops.setRoundingIncrement(exportedProperties.getRoundingIncrement()); 2214 } 2215 return PatternStringUtils.propertiesToPatternString(tprops); 2216 } 2217 2218 /** 2219 * Calls {@link #toPattern} and converts the string to localized notation. For more information on 2220 * localized notation, see {@link #applyLocalizedPattern}. This method is provided for backwards 2221 * compatibility and should not be used in new projects. 2222 * 2223 * @return A decimal format pattern string in localized notation. 2224 */ 2225 public synchronized String toLocalizedPattern() { 2226 String pattern = toPattern(); 2227 return PatternStringUtils.convertLocalized(pattern, symbols, true); 2228 } 2229 2230 /** 2231 * Converts this DecimalFormat to a NumberFormatter. Starting in ICU 60, 2232 * NumberFormatter is the recommended way to format numbers. 2233 * 2234 * @return An instance of {@link LocalizedNumberFormatter} with the same behavior as this instance of 2235 * DecimalFormat. 2236 * @see NumberFormatter 2237 * @hide draft / provisional / internal are hidden on Android 2238 */ 2239 public LocalizedNumberFormatter toNumberFormatter() { 2240 return formatter; 2241 } 2242 2243 /** 2244 * @deprecated This API is ICU internal only. 2245 * @hide draft / provisional / internal are hidden on Android 2246 */ 2247 @Deprecated 2248 public IFixedDecimal getFixedDecimal(double number) { 2249 return formatter.format(number).getFixedDecimal(); 2250 } 2251 2252 private static final ThreadLocal<DecimalFormatProperties> threadLocalProperties = 2253 new ThreadLocal<DecimalFormatProperties>() { 2254 @Override 2255 protected DecimalFormatProperties initialValue() { 2256 return new DecimalFormatProperties(); 2257 } 2258 }; 2259 2260 /** Rebuilds the formatter object from the property bag. */ 2261 void refreshFormatter() { 2262 if (exportedProperties == null) { 2263 // exportedProperties is null only when the formatter is not ready yet. 2264 // The only time when this happens is during legacy deserialization. 2265 return; 2266 } 2267 ULocale locale = this.getLocale(ULocale.ACTUAL_LOCALE); 2268 if (locale == null) { 2269 // Constructor 2270 locale = symbols.getLocale(ULocale.ACTUAL_LOCALE); 2271 } 2272 if (locale == null) { 2273 // Deserialization 2274 locale = symbols.getULocale(); 2275 } 2276 assert locale != null; 2277 formatter = NumberFormatter.fromDecimalFormat(properties, symbols, exportedProperties).locale(locale); 2278 } 2279 2280 /** 2281 * Converts a java.math.BigDecimal to a android.icu.math.BigDecimal with fallback for numbers 2282 * outside of the range supported by android.icu.math.BigDecimal. 2283 * 2284 * @param number 2285 * @return 2286 */ 2287 private Number safeConvertBigDecimal(java.math.BigDecimal number) { 2288 try { 2289 return new android.icu.math.BigDecimal(number); 2290 } catch (NumberFormatException e) { 2291 if (number.signum() > 0 && number.scale() < 0) { 2292 return Double.POSITIVE_INFINITY; 2293 } else if (number.scale() < 0) { 2294 return Double.NEGATIVE_INFINITY; 2295 } else if (number.signum() < 0) { 2296 return -0.0; 2297 } else { 2298 return 0.0; 2299 } 2300 } 2301 } 2302 2303 /** 2304 * Returns true if the currency is set in The property bag or if currency symbols are present in 2305 * the prefix/suffix pattern. 2306 */ 2307 private static boolean useCurrency(DecimalFormatProperties properties) { 2308 return ((properties.getCurrency() != null) 2309 || properties.getCurrencyPluralInfo() != null 2310 || properties.getCurrencyUsage() != null 2311 || AffixUtils.hasCurrencySymbols(properties.getPositivePrefixPattern()) 2312 || AffixUtils.hasCurrencySymbols(properties.getPositiveSuffixPattern()) 2313 || AffixUtils.hasCurrencySymbols(properties.getNegativePrefixPattern()) 2314 || AffixUtils.hasCurrencySymbols(properties.getNegativeSuffixPattern())); 2315 } 2316 2317 /** 2318 * Updates the property bag with settings from the given pattern. 2319 * 2320 * @param pattern The pattern string to parse. 2321 * @param ignoreRounding Whether to leave out rounding information (minFrac, maxFrac, and rounding 2322 * increment) when parsing the pattern. This may be desirable if a custom rounding mode, such 2323 * as CurrencyUsage, is to be used instead. One of {@link 2324 * PatternStringParser#IGNORE_ROUNDING_ALWAYS}, {@link PatternStringParser#IGNORE_ROUNDING_IF_CURRENCY}, 2325 * or {@link PatternStringParser#IGNORE_ROUNDING_NEVER}. 2326 * @see PatternAndPropertyUtils#parseToExistingProperties 2327 */ 2328 void setPropertiesFromPattern(String pattern, int ignoreRounding) { 2329 if (pattern == null) { 2330 throw new NullPointerException(); 2331 } 2332 PatternStringParser.parseToExistingProperties(pattern, properties, ignoreRounding); 2333 } 2334 2335 /** 2336 * @deprecated This API is ICU internal only. 2337 * @hide draft / provisional / internal are hidden on Android 2338 */ 2339 @Deprecated 2340 public synchronized void setProperties(PropertySetter func) { 2341 func.set(properties); 2342 refreshFormatter(); 2343 } 2344 2345 /** 2346 * @deprecated This API is ICU internal only. 2347 * @hide draft / provisional / internal are hidden on Android 2348 */ 2349 @Deprecated 2350 public static interface PropertySetter { 2351 /** 2352 * @deprecated This API is ICU internal only. 2353 * @hide draft / provisional / internal are hidden on Android 2354 */ 2355 @Deprecated 2356 public void set(DecimalFormatProperties props); 2357 } 2358 2359 /** 2360 * <strong>[icu]</strong> Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to specify pad 2361 * characters inserted before the prefix. 2362 * 2363 * @see #setPadPosition 2364 * @see #getPadPosition 2365 * @see #PAD_AFTER_PREFIX 2366 * @see #PAD_BEFORE_SUFFIX 2367 * @see #PAD_AFTER_SUFFIX 2368 */ 2369 public static final int PAD_BEFORE_PREFIX = 0; 2370 2371 /** 2372 * <strong>[icu]</strong> Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to specify pad 2373 * characters inserted after the prefix. 2374 * 2375 * @see #setPadPosition 2376 * @see #getPadPosition 2377 * @see #PAD_BEFORE_PREFIX 2378 * @see #PAD_BEFORE_SUFFIX 2379 * @see #PAD_AFTER_SUFFIX 2380 */ 2381 public static final int PAD_AFTER_PREFIX = 1; 2382 2383 /** 2384 * <strong>[icu]</strong> Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to specify pad 2385 * characters inserted before the suffix. 2386 * 2387 * @see #setPadPosition 2388 * @see #getPadPosition 2389 * @see #PAD_BEFORE_PREFIX 2390 * @see #PAD_AFTER_PREFIX 2391 * @see #PAD_AFTER_SUFFIX 2392 */ 2393 public static final int PAD_BEFORE_SUFFIX = 2; 2394 2395 /** 2396 * <strong>[icu]</strong> Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to specify pad 2397 * characters inserted after the suffix. 2398 * 2399 * @see #setPadPosition 2400 * @see #getPadPosition 2401 * @see #PAD_BEFORE_PREFIX 2402 * @see #PAD_AFTER_PREFIX 2403 * @see #PAD_BEFORE_SUFFIX 2404 */ 2405 public static final int PAD_AFTER_SUFFIX = 3; 2406 } 2407