LEFT | RIGHT |
1 // © 2017 and later: Unicode, Inc. and others. | 1 // © 2017 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 package com.ibm.icu.text; | 3 package com.ibm.icu.text; |
4 | 4 |
5 import java.io.IOException; | 5 import java.io.IOException; |
6 import java.io.ObjectInputStream; | 6 import java.io.ObjectInputStream; |
7 import java.io.ObjectOutputStream; | 7 import java.io.ObjectOutputStream; |
| 8 import java.io.ObjectStreamField; |
8 import java.math.BigInteger; | 9 import java.math.BigInteger; |
9 import java.math.RoundingMode; | 10 import java.math.RoundingMode; |
10 import java.text.AttributedCharacterIterator; | 11 import java.text.AttributedCharacterIterator; |
11 import java.text.FieldPosition; | 12 import java.text.FieldPosition; |
12 import java.text.ParseException; | 13 import java.text.ParseException; |
13 import java.text.ParsePosition; | 14 import java.text.ParsePosition; |
14 | 15 |
15 import com.ibm.icu.impl.number.AffixPatternUtils; | 16 import com.ibm.icu.impl.number.AffixPatternUtils; |
16 import com.ibm.icu.impl.number.Endpoint; | 17 import com.ibm.icu.impl.number.Endpoint; |
17 import com.ibm.icu.impl.number.Format.SingularFormat; | 18 import com.ibm.icu.impl.number.Format.SingularFormat; |
18 import com.ibm.icu.impl.number.FormatQuantity4; | 19 import com.ibm.icu.impl.number.FormatQuantity4; |
19 import com.ibm.icu.impl.number.Parse; | 20 import com.ibm.icu.impl.number.Parse; |
20 import com.ibm.icu.impl.number.PatternString; | 21 import com.ibm.icu.impl.number.PatternString; |
21 import com.ibm.icu.impl.number.Properties; | 22 import com.ibm.icu.impl.number.Properties; |
22 import com.ibm.icu.impl.number.formatters.PaddingFormat.PaddingLocation; | 23 import com.ibm.icu.impl.number.formatters.PaddingFormat.PadPosition; |
23 import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat; | 24 import com.ibm.icu.impl.number.formatters.PositiveDecimalFormat; |
24 import com.ibm.icu.impl.number.formatters.ScientificFormat; | 25 import com.ibm.icu.impl.number.formatters.ScientificFormat; |
25 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder; | 26 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder; |
| 27 import com.ibm.icu.impl.number.rounders.SignificantDigitsRounder.SignificantDigi
tsMode; |
| 28 import com.ibm.icu.lang.UCharacter; |
26 import com.ibm.icu.math.BigDecimal; | 29 import com.ibm.icu.math.BigDecimal; |
27 import com.ibm.icu.math.MathContext; | 30 import com.ibm.icu.math.MathContext; |
28 import com.ibm.icu.text.PluralRules.IFixedDecimal; | 31 import com.ibm.icu.text.PluralRules.IFixedDecimal; |
29 import com.ibm.icu.util.Currency; | 32 import com.ibm.icu.util.Currency; |
30 import com.ibm.icu.util.Currency.CurrencyUsage; | 33 import com.ibm.icu.util.Currency.CurrencyUsage; |
31 import com.ibm.icu.util.CurrencyAmount; | 34 import com.ibm.icu.util.CurrencyAmount; |
32 import com.ibm.icu.util.ULocale; | 35 import com.ibm.icu.util.ULocale; |
33 | 36 |
34 /** @author sffc */ | 37 /** @stable ICU 2.0 */ |
35 public class DecimalFormat extends NumberFormat { | 38 public class DecimalFormat extends NumberFormat { |
36 | 39 |
37 /** | 40 /** New serialization in ICU 59: declare different version from ICU 58. */ |
38 * New serialization in ICU 59: declare different version from ICU 58. | 41 private static final long serialVersionUID = 864413376551465018L; |
39 */ | 42 |
40 private static final long serialVersionUID = 864413376551465019L; | 43 /** |
41 | 44 * One non-transient field such that deserialization can determine the version
of the class. This |
42 /// INSTANCE VARIABLES /// | 45 * field has existed since the very earliest versions of DecimalFormat. |
43 // Access level: package-private, so that subclasses can use them. | 46 */ |
| 47 @SuppressWarnings("unused") |
| 48 private final int serialVersionOnStream = 5; |
| 49 |
| 50 //============================================================================
=========// |
| 51 // INSTANCE FIELDS
// |
| 52 //============================================================================
=========// |
| 53 |
| 54 // Fields are package-private, so that subclasses can use them. |
44 // properties should be final, but clone won't work if we make it final. | 55 // properties should be final, but clone won't work if we make it final. |
45 // All fields are transient because custom serialization is used. | 56 // All fields are transient because custom serialization is used. |
46 | 57 |
47 /** | 58 /** |
48 * The property bag corresponding to user-specified settings and settings from
the pattern | 59 * The property bag corresponding to user-specified settings and settings from
the pattern string. |
49 * string. In principle this should be final, but serialize and clone won't w
ork if it is | 60 * In principle this should be final, but serialize and clone won't work if it
is final. Does not |
50 * final. Does not need to be volatile because the reference never changes. | 61 * need to be volatile because the reference never changes. |
51 */ | 62 */ |
52 /* final */ transient Properties properties; | 63 /* final */ transient Properties properties; |
53 | 64 |
54 /** | 65 /** |
55 * The symbols for the current locale. Volatile because threads may read and
write at the same | 66 * The symbols for the current locale. Volatile because threads may read and w
rite at the same |
56 * time. | 67 * time. |
57 */ | 68 */ |
58 volatile transient DecimalFormatSymbols symbols; | 69 transient volatile DecimalFormatSymbols symbols; |
59 | 70 |
60 /** | 71 /** |
61 * The pre-computed formatter object. Setters cause this to be re-computed at
omically. The | 72 * The pre-computed formatter object. Setters cause this to be re-computed ato
mically. The {@link |
62 * {@link #format} method uses the formatter directly without needing to synch
ronize. Volatile | 73 * #format} method uses the formatter directly without needing to synchronize.
Volatile because |
63 * because threads may read and write at the same time. | 74 * threads may read and write at the same time. |
64 */ | 75 */ |
65 volatile transient SingularFormat formatter; | 76 transient volatile SingularFormat formatter; |
66 | 77 |
67 /** | 78 /** |
68 * The effective properties as exported from the formatter object. Volatile b
ecause threads may | 79 * The effective properties as exported from the formatter object. Volatile be
cause threads may |
69 * read and write at the same time. | 80 * read and write at the same time. |
70 */ | 81 */ |
71 volatile transient Properties exportedProperties; | 82 transient volatile Properties exportedProperties; |
| 83 |
| 84 //============================================================================
=========// |
| 85 // CONSTRUCTORS
// |
| 86 //============================================================================
=========// |
72 | 87 |
73 /** @stable ICU 2.0 */ | 88 /** @stable ICU 2.0 */ |
74 public DecimalFormat() { | 89 public DecimalFormat() { |
75 // Use the locale's default pattern | 90 // Use the locale's default pattern |
76 ULocale def = ULocale.getDefault(ULocale.Category.FORMAT); | 91 ULocale def = ULocale.getDefault(ULocale.Category.FORMAT); |
77 String pattern = getPattern(def, 0); | 92 String pattern = getPattern(def, 0); |
78 symbols = getDefaultSymbols(); | 93 symbols = getDefaultSymbols(); |
79 properties = new Properties(); | 94 properties = new Properties(); |
80 exportedProperties = new Properties(); | 95 exportedProperties = new Properties(); |
81 // Regression: ignore pattern rounding information if the pattern has curren
cy symbols. | 96 // Regression: ignore pattern rounding information if the pattern has curren
cy symbols. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 this.symbols = (DecimalFormatSymbols) symbols.clone(); | 136 this.symbols = (DecimalFormatSymbols) symbols.clone(); |
122 properties = new Properties(); | 137 properties = new Properties(); |
123 exportedProperties = new Properties(); | 138 exportedProperties = new Properties(); |
124 // If choice is a currency type, ignore the rounding information. | 139 // If choice is a currency type, ignore the rounding information. |
125 if (choice == CURRENCYSTYLE | 140 if (choice == CURRENCYSTYLE |
126 || choice == ISOCURRENCYSTYLE | 141 || choice == ISOCURRENCYSTYLE |
127 || choice == ACCOUNTINGCURRENCYSTYLE | 142 || choice == ACCOUNTINGCURRENCYSTYLE |
128 || choice == CASHCURRENCYSTYLE | 143 || choice == CASHCURRENCYSTYLE |
129 || choice == STANDARDCURRENCYSTYLE | 144 || choice == STANDARDCURRENCYSTYLE |
130 || choice == PLURALCURRENCYSTYLE | 145 || choice == PLURALCURRENCYSTYLE |
131 || AffixPatternUtils.hasCurrencySymbols(pattern)){ | 146 || AffixPatternUtils.hasCurrencySymbols(pattern)) { |
132 setPropertiesFromPattern(pattern, true); | 147 setPropertiesFromPattern(pattern, true); |
133 } else { | 148 } else { |
134 setPropertiesFromPattern(pattern, false); | 149 setPropertiesFromPattern(pattern, false); |
135 } | 150 } |
136 refreshFormatter(); | 151 refreshFormatter(); |
137 } | 152 } |
138 | 153 |
139 /** @stable ICU 2.0 */ | 154 private static DecimalFormatSymbols getDefaultSymbols() { |
140 @Override | |
141 public Object clone() { | |
142 DecimalFormat other = (DecimalFormat) super.clone(); | |
143 other.symbols = (DecimalFormatSymbols) symbols.clone(); | |
144 other.properties = properties.clone(); | |
145 other.exportedProperties = new Properties(); | |
146 other.refreshFormatter(); | |
147 return other; | |
148 } | |
149 | |
150 /** | |
151 * Custom serialization: save property bag and symbols; the formatter object c
an be re-created | |
152 * from just that amount of information. | |
153 */ | |
154 private void writeObject(ObjectOutputStream oos) throws IOException { | |
155 oos.defaultWriteObject(); | |
156 // ICU 59 custom serialization. | |
157 // Extra int for possible future use | |
158 oos.writeInt(0); | |
159 // 1) Property Bag | |
160 oos.writeObject(properties); | |
161 // 2) DecimalFormatSymbols | |
162 oos.writeObject(symbols); | |
163 } | |
164 | |
165 /** | |
166 * Custom serialization: re-create object from serialized property bag and sym
bols. | |
167 */ | |
168 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFou
ndException { | |
169 ois.defaultReadObject(); | |
170 // Extra int for possible future use | |
171 ois.readInt(); | |
172 // 1) Property Bag | |
173 properties = (Properties) ois.readObject(); | |
174 // 2) DecimalFormatSymbols | |
175 symbols = (DecimalFormatSymbols) ois.readObject(); | |
176 // Re-build transient fields | |
177 exportedProperties = new Properties(); | |
178 refreshFormatter(); | |
179 } | |
180 | |
181 static DecimalFormatSymbols getDefaultSymbols() { | |
182 return DecimalFormatSymbols.getInstance(); | 155 return DecimalFormatSymbols.getInstance(); |
183 } | 156 } |
184 | 157 |
185 /** @stable ICU 2.0 */ | 158 /** |
| 159 * Parses the given pattern string and overwrites the settings specified in th
e pattern string. |
| 160 * The properties corresponding to the following setters are overwritten, eith
er with their |
| 161 * default values or with the value specified in the pattern string: |
| 162 * |
| 163 * <ol> |
| 164 * <li>{@link #setDecimalSeparatorAlwaysShown} |
| 165 * <li>{@link #setExponentSignAlwaysShown} |
| 166 * <li>{@link #setFormatWidth} |
| 167 * <li>{@link #setGroupingSize} |
| 168 * <li>{@link #setMultiplier} (percent/permille) |
| 169 * <li>{@link #setMaximumFractionDigits} |
| 170 * <li>{@link #setMaximumIntegerDigits} |
| 171 * <li>{@link #setMaximumSignificantDigits} |
| 172 * <li>{@link #setMinimumExponentDigits} |
| 173 * <li>{@link #setMinimumFractionDigits} |
| 174 * <li>{@link #setMinimumIntegerDigits} |
| 175 * <li>{@link #setMinimumSignificantDigits} |
| 176 * <li>{@link #setPadPosition} |
| 177 * <li>{@link #setPadCharacter} |
| 178 * <li>{@link #setRoundingIncrement} |
| 179 * <li>{@link #setSecondaryGroupingSize} |
| 180 * </ol> |
| 181 * |
| 182 * All other settings remain untouched. |
| 183 * |
| 184 * <p>For more information on pattern strings, see <a |
| 185 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patte
rns">UTS #35</a>. |
| 186 * |
| 187 * @stable ICU 2.0 |
| 188 */ |
186 public synchronized void applyPattern(String pattern) { | 189 public synchronized void applyPattern(String pattern) { |
187 setPropertiesFromPattern(pattern, false); | 190 setPropertiesFromPattern(pattern, false); |
188 // Backwards compatibility: clear out user-specified prefix and suffix, | 191 // Backwards compatibility: clear out user-specified prefix and suffix, |
189 // as well as CurrencyPluralInfo. | 192 // as well as CurrencyPluralInfo. |
190 properties.setPositivePrefix(null); | 193 properties.setPositivePrefix(null); |
191 properties.setNegativePrefix(null); | 194 properties.setNegativePrefix(null); |
192 properties.setPositiveSuffix(null); | 195 properties.setPositiveSuffix(null); |
193 properties.setNegativeSuffix(null); | 196 properties.setNegativeSuffix(null); |
194 properties.setCurrencyPluralInfo(null); | 197 properties.setCurrencyPluralInfo(null); |
195 refreshFormatter(); | 198 refreshFormatter(); |
196 } | 199 } |
197 | 200 |
198 /** @stable ICU 2.0 */ | 201 /** |
| 202 * Converts the given string to standard notation and then parses it using {@l
ink #applyPattern}. |
| 203 * |
| 204 * <p>Localized notation means that instead of using generic placeholders in t
he pattern, you use |
| 205 * the corresponding locale-specific characters instead. For example, in local
e <em>fr-FR</em>, |
| 206 * the period in the pattern "0.000" means "decimal" in standard notation (as
it does in every |
| 207 * other locale), but it means "grouping" in localized notation. |
| 208 * |
| 209 * @param localizedPattern The pattern string in localized notation. |
| 210 * @stable ICU 2.0 |
| 211 */ |
199 public synchronized void applyLocalizedPattern(String localizedPattern) { | 212 public synchronized void applyLocalizedPattern(String localizedPattern) { |
200 String pattern = PatternString.convertLocalized(localizedPattern, symbols, f
alse); | 213 String pattern = PatternString.convertLocalized(localizedPattern, symbols, f
alse); |
201 applyPattern(pattern); | 214 applyPattern(pattern); |
202 } | 215 } |
203 | 216 |
204 /** | 217 //============================================================================
=========// |
205 * {@inheritDoc} | 218 // CLONE AND SERIALIZE
// |
206 * | 219 //============================================================================
=========// |
207 * @stable ICU 2.0 | 220 |
208 */ | 221 /** @stable ICU 2.0 */ |
| 222 @Override |
| 223 public Object clone() { |
| 224 DecimalFormat other = (DecimalFormat) super.clone(); |
| 225 other.symbols = (DecimalFormatSymbols) symbols.clone(); |
| 226 other.properties = properties.clone(); |
| 227 other.exportedProperties = new Properties(); |
| 228 other.refreshFormatter(); |
| 229 return other; |
| 230 } |
| 231 |
| 232 /** |
| 233 * Custom serialization: save property bag and symbols; the formatter object c
an be re-created |
| 234 * from just that amount of information. |
| 235 */ |
| 236 private void writeObject(ObjectOutputStream oos) throws IOException { |
| 237 // ICU 59 custom serialization. |
| 238 // Write class metadata and serialVersionOnStream field: |
| 239 oos.defaultWriteObject(); |
| 240 // Extra int for possible future use: |
| 241 oos.writeInt(0); |
| 242 // 1) Property Bag |
| 243 oos.writeObject(properties); |
| 244 // 2) DecimalFormatSymbols |
| 245 oos.writeObject(symbols); |
| 246 } |
| 247 |
| 248 /** |
| 249 * Custom serialization: re-create object from serialized property bag and sym
bols. Also supports |
| 250 * reading from the legacy (pre-ICU4J 59) format and converting it to the new
form. |
| 251 */ |
| 252 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFou
ndException { |
| 253 ObjectInputStream.GetField fieldGetter = ois.readFields(); |
| 254 ObjectStreamField[] serializedFields = fieldGetter.getObjectStreamClass().ge
tFields(); |
| 255 int serialVersion = fieldGetter.get("serialVersionOnStream", -1); |
| 256 |
| 257 if (serialVersion > 5) { |
| 258 throw new IOException( |
| 259 "Cannot deserialize newer com.ibm.icu.text.DecimalFormat (v" + serialV
ersion + ")"); |
| 260 } else if (serialVersion == 5) { |
| 261 ///// ICU 59+ SERIALIZATION FORMAT ///// |
| 262 // We expect this field and no other fields: |
| 263 if (serializedFields.length > 1) { |
| 264 throw new IOException("Too many fields when reading serial version 5"); |
| 265 } |
| 266 // Extra int for possible future use: |
| 267 ois.readInt(); |
| 268 // 1) Property Bag |
| 269 properties = (Properties) ois.readObject(); |
| 270 // 2) DecimalFormatSymbols |
| 271 symbols = (DecimalFormatSymbols) ois.readObject(); |
| 272 // Re-build transient fields |
| 273 exportedProperties = new Properties(); |
| 274 refreshFormatter(); |
| 275 } else { |
| 276 ///// LEGACY SERIALIZATION FORMAT ///// |
| 277 properties = new Properties(); |
| 278 // Loop through the fields. Not all fields necessarily exist in the serial
ization. |
| 279 String pp = null, ppp = null, ps = null, psp = null; |
| 280 String np = null, npp = null, ns = null, nsp = null; |
| 281 for (ObjectStreamField field : serializedFields) { |
| 282 String name = field.getName(); |
| 283 if (name.equals("decimalSeparatorAlwaysShown")) { |
| 284 setDecimalSeparatorAlwaysShown(fieldGetter.get("decimalSeparatorAlways
Shown", false)); |
| 285 } else if (name.equals("exponentSignAlwaysShown")) { |
| 286 setExponentSignAlwaysShown(fieldGetter.get("exponentSignAlwaysShown",
false)); |
| 287 } else if (name.equals("formatWidth")) { |
| 288 setFormatWidth(fieldGetter.get("formatWidth", 0)); |
| 289 } else if (name.equals("groupingSize")) { |
| 290 setGroupingSize(fieldGetter.get("groupingSize", (byte) 3)); |
| 291 } else if (name.equals("groupingSize2")) { |
| 292 setSecondaryGroupingSize(fieldGetter.get("groupingSize2", (byte) 0)); |
| 293 } else if (name.equals("maxSignificantDigits")) { |
| 294 setMaximumSignificantDigits(fieldGetter.get("maxSignificantDigits", 6)
); |
| 295 } else if (name.equals("minExponentDigits")) { |
| 296 setMinimumExponentDigits(fieldGetter.get("minExponentDigits", (byte) 0
)); |
| 297 } else if (name.equals("minSignificantDigits")) { |
| 298 setMinimumSignificantDigits(fieldGetter.get("minSignificantDigits", 1)
); |
| 299 } else if (name.equals("multiplier")) { |
| 300 setMultiplier(fieldGetter.get("multiplier", 1)); |
| 301 } else if (name.equals("pad")) { |
| 302 setPadCharacter(fieldGetter.get("pad", '\u0020')); |
| 303 } else if (name.equals("padPosition")) { |
| 304 setPadPosition(fieldGetter.get("padPosition", 0)); |
| 305 } else if (name.equals("parseBigDecimal")) { |
| 306 setParseBigDecimal(fieldGetter.get("parseBigDecimal", false)); |
| 307 } else if (name.equals("parseRequireDecimalPoint")) { |
| 308 setDecimalPatternMatchRequired(fieldGetter.get("parseRequireDecimalPoi
nt", false)); |
| 309 } else if (name.equals("roundingMode")) { |
| 310 setRoundingMode(fieldGetter.get("roundingMode", 0)); |
| 311 } else if (name.equals("useExponentialNotation")) { |
| 312 setScientificNotation(fieldGetter.get("useExponentialNotation", false)
); |
| 313 } else if (name.equals("useSignificantDigits")) { |
| 314 setSignificantDigitsUsed(fieldGetter.get("useSignificantDigits", false
)); |
| 315 } else if (name.equals("currencyPluralInfo")) { |
| 316 setCurrencyPluralInfo((CurrencyPluralInfo) fieldGetter.get("currencyPl
uralInfo", null)); |
| 317 } else if (name.equals("currencyUsage")) { |
| 318 setCurrencyUsage((CurrencyUsage) fieldGetter.get("currencyUsage", null
)); |
| 319 } else if (name.equals("mathContext")) { |
| 320 setMathContextICU((MathContext) fieldGetter.get("mathContext", null)); |
| 321 } else if (name.equals("negPrefixPattern")) { |
| 322 npp = (String) fieldGetter.get("negPrefixPattern", null); |
| 323 } else if (name.equals("negSuffixPattern")) { |
| 324 nsp = (String) fieldGetter.get("negSuffixPattern", null); |
| 325 } else if (name.equals("negativePrefix")) { |
| 326 np = (String) fieldGetter.get("negativePrefix", null); |
| 327 } else if (name.equals("negativeSuffix")) { |
| 328 ns = (String) fieldGetter.get("negativeSuffix", null); |
| 329 } else if (name.equals("posPrefixPattern")) { |
| 330 ppp = (String) fieldGetter.get("posPrefixPattern", null); |
| 331 } else if (name.equals("posSuffixPattern")) { |
| 332 psp = (String) fieldGetter.get("posSuffixPattern", null); |
| 333 } else if (name.equals("positivePrefix")) { |
| 334 pp = (String) fieldGetter.get("positivePrefix", null); |
| 335 } else if (name.equals("positiveSuffix")) { |
| 336 ps = (String) fieldGetter.get("positiveSuffix", null); |
| 337 } else if (name.equals("roundingIncrement")) { |
| 338 setRoundingIncrement((java.math.BigDecimal) fieldGetter.get("roundingI
ncrement", null)); |
| 339 } else if (name.equals("symbols")) { |
| 340 setDecimalFormatSymbols((DecimalFormatSymbols) fieldGetter.get("symbol
s", null)); |
| 341 } else { |
| 342 // The following fields are ignored: |
| 343 // "PARSE_MAX_EXPONENT" |
| 344 // "currencySignCount" |
| 345 // "style" |
| 346 // "attributes" |
| 347 // "currencyChoice" |
| 348 // "formatPattern" |
| 349 } |
| 350 } |
| 351 // Resolve affixes |
| 352 if (npp == null) { |
| 353 properties.setNegativePrefix(np); |
| 354 } else { |
| 355 properties.setNegativePrefixPattern(npp); |
| 356 } |
| 357 if (nsp == null) { |
| 358 properties.setNegativeSuffix(ns); |
| 359 } else { |
| 360 properties.setNegativeSuffixPattern(nsp); |
| 361 } |
| 362 if (ppp == null) { |
| 363 properties.setPositivePrefix(pp); |
| 364 } else { |
| 365 properties.setPositivePrefixPattern(ppp); |
| 366 } |
| 367 if (psp == null) { |
| 368 properties.setPositiveSuffix(ps); |
| 369 } else { |
| 370 properties.setPositiveSuffixPattern(psp); |
| 371 } |
| 372 // Extract values from parent NumberFormat class. Have to use reflection
here. |
| 373 java.lang.reflect.Field getter; |
| 374 try { |
| 375 getter = NumberFormat.class.getDeclaredField("groupingUsed"); |
| 376 getter.setAccessible(true); |
| 377 setGroupingUsed((Boolean) getter.get(this)); |
| 378 getter = NumberFormat.class.getDeclaredField("parseIntegerOnly"); |
| 379 getter.setAccessible(true); |
| 380 setParseIntegerOnly((Boolean) getter.get(this)); |
| 381 getter = NumberFormat.class.getDeclaredField("maximumIntegerDigits"); |
| 382 getter.setAccessible(true); |
| 383 setMaximumIntegerDigits((Integer) getter.get(this)); |
| 384 getter = NumberFormat.class.getDeclaredField("minimumIntegerDigits"); |
| 385 getter.setAccessible(true); |
| 386 setMinimumIntegerDigits((Integer) getter.get(this)); |
| 387 getter = NumberFormat.class.getDeclaredField("maximumFractionDigits"); |
| 388 getter.setAccessible(true); |
| 389 setMaximumFractionDigits((Integer) getter.get(this)); |
| 390 getter = NumberFormat.class.getDeclaredField("minimumFractionDigits"); |
| 391 getter.setAccessible(true); |
| 392 setMinimumFractionDigits((Integer) getter.get(this)); |
| 393 getter = NumberFormat.class.getDeclaredField("currency"); |
| 394 getter.setAccessible(true); |
| 395 setCurrency((Currency) getter.get(this)); |
| 396 getter = NumberFormat.class.getDeclaredField("parseStrict"); |
| 397 getter.setAccessible(true); |
| 398 setParseStrict((Boolean) getter.get(this)); |
| 399 } catch (IllegalArgumentException e) { |
| 400 throw new IOException(e); |
| 401 } catch (IllegalAccessException e) { |
| 402 throw new IOException(e); |
| 403 } catch (NoSuchFieldException e) { |
| 404 throw new IOException(e); |
| 405 } catch (SecurityException e) { |
| 406 throw new IOException(e); |
| 407 } |
| 408 // Finish initialization |
| 409 if (symbols == null) { |
| 410 symbols = getDefaultSymbols(); |
| 411 } |
| 412 exportedProperties = new Properties(); |
| 413 refreshFormatter(); |
| 414 } |
| 415 } |
| 416 |
| 417 //============================================================================
=========// |
| 418 // FORMAT AND PARSE APIS
// |
| 419 //============================================================================
=========// |
| 420 |
| 421 /** @stable ICU 2.0 */ |
209 @Override | 422 @Override |
210 public StringBuffer format(double number, StringBuffer result, FieldPosition f
ieldPosition) { | 423 public StringBuffer format(double number, StringBuffer result, FieldPosition f
ieldPosition) { |
211 FormatQuantity4 fq = new FormatQuantity4(number); | 424 FormatQuantity4 fq = new FormatQuantity4(number); |
212 formatter.format(fq, result, fieldPosition); | 425 formatter.format(fq, result, fieldPosition); |
213 fq.populateUFieldPosition(fieldPosition); | 426 fq.populateUFieldPosition(fieldPosition); |
214 return result; | 427 return result; |
215 } | 428 } |
216 | 429 |
217 /** @stable ICU 2.0 */ | 430 /** @stable ICU 2.0 */ |
218 @Override | 431 @Override |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { | 469 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { |
257 if (!(obj instanceof Number)) throw new IllegalArgumentException(); | 470 if (!(obj instanceof Number)) throw new IllegalArgumentException(); |
258 Number number = (Number) obj; | 471 Number number = (Number) obj; |
259 FormatQuantity4 fq = new FormatQuantity4(number); | 472 FormatQuantity4 fq = new FormatQuantity4(number); |
260 AttributedCharacterIterator result = formatter.formatToCharacterIterator(fq)
; | 473 AttributedCharacterIterator result = formatter.formatToCharacterIterator(fq)
; |
261 return result; | 474 return result; |
262 } | 475 } |
263 | 476 |
264 protected static final ThreadLocal<Properties> threadLocalCurrencyProperties = | 477 protected static final ThreadLocal<Properties> threadLocalCurrencyProperties = |
265 new ThreadLocal<Properties>() { | 478 new ThreadLocal<Properties>() { |
266 @Override | 479 @Override |
267 protected Properties initialValue() { | 480 protected Properties initialValue() { |
268 return new Properties(); | 481 return new Properties(); |
269 } | 482 } |
270 }; | 483 }; |
271 | 484 |
272 @Override | 485 @Override |
273 public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, Fi
eldPosition pos) { | 486 public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, Fi
eldPosition pos) { |
274 // TODO: This is ugly. Currency should be a free parameter, not in property
bag. Fix in ICU 60. | 487 // TODO: This is ugly (although not as ugly as it was in ICU 58). |
| 488 // Currency should be a free parameter, not in property bag. Fix in ICU 60. |
275 Properties cprops = threadLocalCurrencyProperties.get(); | 489 Properties cprops = threadLocalCurrencyProperties.get(); |
276 synchronized(this) { | 490 synchronized (this) { |
277 cprops.copyFrom(properties); | 491 cprops.copyFrom(properties); |
278 } | 492 } |
279 cprops.setCurrency(currAmt.getCurrency()); | 493 cprops.setCurrency(currAmt.getCurrency()); |
280 FormatQuantity4 fq = new FormatQuantity4(currAmt.getNumber()); | 494 FormatQuantity4 fq = new FormatQuantity4(currAmt.getNumber()); |
281 // TODO: Use a static format path here | 495 // TODO: Use a static format path here |
282 SingularFormat fmt = Endpoint.fromBTA(cprops, symbols); | 496 SingularFormat fmt = Endpoint.fromBTA(cprops, symbols); |
283 fmt.format(fq, toAppendTo, pos); | 497 fmt.format(fq, toAppendTo, pos); |
284 fq.populateUFieldPosition(pos); | 498 fq.populateUFieldPosition(pos); |
285 return toAppendTo; | 499 return toAppendTo; |
286 } | 500 } |
(...skipping 21 matching lines...) Expand all Loading... |
308 if (number instanceof java.math.BigDecimal) { | 522 if (number instanceof java.math.BigDecimal) { |
309 number = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) number); | 523 number = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) number); |
310 result = new CurrencyAmount(number, result.getCurrency()); | 524 result = new CurrencyAmount(number, result.getCurrency()); |
311 } | 525 } |
312 return result; | 526 return result; |
313 } catch (ParseException e) { | 527 } catch (ParseException e) { |
314 return null; | 528 return null; |
315 } | 529 } |
316 } | 530 } |
317 | 531 |
318 /** | 532 //============================================================================
=========// |
319 * Returns a copy of the decimal format symbols used by this format. | 533 // GETTERS AND SETTERS
// |
| 534 //============================================================================
=========// |
| 535 |
| 536 /** |
| 537 * Returns a copy of the decimal format symbols used by this formatter. |
320 * | 538 * |
321 * @return desired DecimalFormatSymbols | 539 * @return desired DecimalFormatSymbols |
322 * @see DecimalFormatSymbols | 540 * @see DecimalFormatSymbols |
323 * @stable ICU 2.0 | 541 * @stable ICU 2.0 |
324 */ | 542 */ |
325 public synchronized DecimalFormatSymbols getDecimalFormatSymbols() { | 543 public synchronized DecimalFormatSymbols getDecimalFormatSymbols() { |
326 return (DecimalFormatSymbols) symbols.clone(); | 544 return (DecimalFormatSymbols) symbols.clone(); |
327 } | 545 } |
328 | 546 |
329 /** | 547 /** |
330 * Sets the decimal format symbols used by this format. The format uses a copy
of the provided | 548 * Sets the decimal format symbols used by this formatter. The formatter uses
a copy of the |
331 * symbols. | 549 * provided symbols. |
332 * | 550 * |
333 * @param newSymbols desired DecimalFormatSymbols | 551 * @param newSymbols desired DecimalFormatSymbols |
334 * @see DecimalFormatSymbols | 552 * @see DecimalFormatSymbols |
335 * @stable ICU 2.0 | 553 * @stable ICU 2.0 |
336 */ | 554 */ |
337 public synchronized void setDecimalFormatSymbols(DecimalFormatSymbols newSymbo
ls) { | 555 public synchronized void setDecimalFormatSymbols(DecimalFormatSymbols newSymbo
ls) { |
338 symbols = (DecimalFormatSymbols) newSymbols.clone(); | 556 symbols = (DecimalFormatSymbols) newSymbols.clone(); |
339 refreshFormatter(); | 557 refreshFormatter(); |
340 } | 558 } |
341 | 559 |
342 /** @stable ICU 2.0 */ | 560 /** |
| 561 * <strong>Affixes:</strong> Gets the positive prefix string currently being u
sed to format |
| 562 * numbers. |
| 563 * |
| 564 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 565 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 566 * If the affix was specified via {@link #setPositivePrefix}, the string will
be returned |
| 567 * literally. |
| 568 * |
| 569 * @return The string being prepended to positive numbers. |
| 570 * @category Affixes |
| 571 * @stable ICU 2.0 |
| 572 */ |
343 public synchronized String getPositivePrefix() { | 573 public synchronized String getPositivePrefix() { |
344 String result = exportedProperties.getPositivePrefix(); | 574 String result = exportedProperties.getPositivePrefix(); |
345 return (result == null) ? "" : result; | 575 return (result == null) ? "" : result; |
346 } | 576 } |
347 | 577 |
348 /** @stable ICU 2.0 */ | 578 /** |
349 public synchronized void setPositivePrefix(String newValue) { | 579 * <strong>Affixes:</strong> Sets the string to prepend to positive numbers. F
or example, if you |
350 properties.setPositivePrefix(newValue); | 580 * set the value "#", then the number 123 will be formatted as "#123" in the l
ocale |
351 refreshFormatter(); | 581 * <em>en-US</em>. |
352 } | 582 * |
353 | 583 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
354 /** @stable ICU 2.0 */ | 584 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 585 * |
| 586 * @param prefix The literal string to prepend to positive numbers. |
| 587 * @category Affixes |
| 588 * @stable ICU 2.0 |
| 589 */ |
| 590 public synchronized void setPositivePrefix(String prefix) { |
| 591 properties.setPositivePrefix(prefix); |
| 592 refreshFormatter(); |
| 593 } |
| 594 |
| 595 /** |
| 596 * <strong>Affixes:</strong> Gets the negative prefix string currently being u
sed to format |
| 597 * numbers. |
| 598 * |
| 599 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 600 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 601 * If the affix was specified via {@link #setNegativePrefix}, the string will
be returned |
| 602 * literally. |
| 603 * |
| 604 * @return The string being prepended to negative numbers. |
| 605 * @category Affixes |
| 606 * @stable ICU 2.0 |
| 607 */ |
355 public synchronized String getNegativePrefix() { | 608 public synchronized String getNegativePrefix() { |
356 String result = exportedProperties.getNegativePrefix(); | 609 String result = exportedProperties.getNegativePrefix(); |
357 return (result == null) ? "" : result; | 610 return (result == null) ? "" : result; |
358 } | 611 } |
359 | 612 |
360 /** @stable ICU 2.0 */ | 613 /** |
361 public synchronized void setNegativePrefix(String newValue) { | 614 * <strong>Affixes:</strong> Sets the string to prepend to negative numbers. F
or example, if you |
362 properties.setNegativePrefix(newValue); | 615 * set the value "#", then the number -123 will be formatted as "#123" in the
locale |
363 refreshFormatter(); | 616 * <em>en-US</em> (overriding the implicit default '-' in the pattern). |
364 } | 617 * |
365 | 618 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
366 /** @stable ICU 2.0 */ | 619 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 620 * |
| 621 * @param suffix The literal string to prepend to negative numbers. |
| 622 * @category Affixes |
| 623 * @stable ICU 2.0 |
| 624 */ |
| 625 public synchronized void setNegativePrefix(String suffix) { |
| 626 properties.setNegativePrefix(suffix); |
| 627 refreshFormatter(); |
| 628 } |
| 629 |
| 630 /** |
| 631 * <strong>Affixes:</strong> Gets the positive suffix string currently being u
sed to format |
| 632 * numbers. |
| 633 * |
| 634 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 635 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 636 * If the affix was specified via {@link #setPositiveSuffix}, the string will
be returned |
| 637 * literally. |
| 638 * |
| 639 * @return The string being appended to positive numbers. |
| 640 * @category Affixes |
| 641 * @stable ICU 2.0 |
| 642 */ |
367 public synchronized String getPositiveSuffix() { | 643 public synchronized String getPositiveSuffix() { |
368 String result = exportedProperties.getPositiveSuffix(); | 644 String result = exportedProperties.getPositiveSuffix(); |
369 return (result == null) ? "" : result; | 645 return (result == null) ? "" : result; |
370 } | 646 } |
371 | 647 |
372 /** @stable ICU 2.0 */ | 648 /** |
373 public synchronized void setPositiveSuffix(String newValue) { | 649 * <strong>Affixes:</strong> Sets the string to append to positive numbers. Fo
r example, if you |
374 properties.setPositiveSuffix(newValue); | 650 * set the value "#", then the number 123 will be formatted as "123#" in the l
ocale |
375 refreshFormatter(); | 651 * <em>en-US</em>. |
376 } | 652 * |
377 | 653 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
378 /** @stable ICU 2.0 */ | 654 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 655 * |
| 656 * @param suffix The literal string to append to positive numbers. |
| 657 * @category Affixes |
| 658 * @stable ICU 2.0 |
| 659 */ |
| 660 public synchronized void setPositiveSuffix(String suffix) { |
| 661 properties.setPositiveSuffix(suffix); |
| 662 refreshFormatter(); |
| 663 } |
| 664 |
| 665 /** |
| 666 * <strong>Affixes:</strong> Gets the negative suffix string currently being u
sed to format |
| 667 * numbers. |
| 668 * |
| 669 * <p>If the affix was specified via the pattern, the string returned by this
method will have |
| 670 * locale symbols substituted in place of special characters according to the
LDML specification. |
| 671 * If the affix was specified via {@link #setNegativeSuffix}, the string will
be returned |
| 672 * literally. |
| 673 * |
| 674 * @return The string being appended to negative numbers. |
| 675 * @category Affixes |
| 676 * @stable ICU 2.0 |
| 677 */ |
379 public synchronized String getNegativeSuffix() { | 678 public synchronized String getNegativeSuffix() { |
380 String result = exportedProperties.getNegativeSuffix(); | 679 String result = exportedProperties.getNegativeSuffix(); |
381 return (result == null) ? "" : result; | 680 return (result == null) ? "" : result; |
382 } | 681 } |
383 | 682 |
384 /** @stable ICU 2.0 */ | 683 /** |
385 public synchronized void setNegativeSuffix(String newValue) { | 684 * <strong>Affixes:</strong> Sets the string to append to negative numbers. Fo
r example, if you |
386 properties.setNegativeSuffix(newValue); | 685 * set the value "#", then the number 123 will be formatted as "123#" in the l
ocale |
387 refreshFormatter(); | 686 * <em>en-US</em>. |
388 } | 687 * |
389 | 688 * <p>Using this method overrides the affix specified via the pattern, and unl
ike the pattern, the |
390 /** @stable ICU 2.0 */ | 689 * string given to this method will be interpreted literally WITHOUT locale sy
mbol substitutions. |
| 690 * |
| 691 * @param suffix The literal string to append to negative numbers. |
| 692 * @category Affixes |
| 693 * @stable ICU 2.0 |
| 694 */ |
| 695 public synchronized void setNegativeSuffix(String suffix) { |
| 696 properties.setNegativeSuffix(suffix); |
| 697 refreshFormatter(); |
| 698 } |
| 699 |
| 700 /** |
| 701 * @return The multiplier being applied to numbers before they are formatted. |
| 702 * @see #setMultiplier |
| 703 * @category Multipliers |
| 704 * @stable ICU 2.0 |
| 705 */ |
391 public synchronized int getMultiplier() { | 706 public synchronized int getMultiplier() { |
392 if (properties.getMultiplier() != null) { | 707 if (properties.getMultiplier() != null) { |
393 return properties.getMultiplier().intValue(); | 708 return properties.getMultiplier().intValue(); |
394 } else { | 709 } else { |
395 return (int) Math.pow(10, properties.getMagnitudeMultiplier()); | 710 return (int) Math.pow(10, properties.getMagnitudeMultiplier()); |
396 } | 711 } |
397 } | 712 } |
398 | 713 |
399 /** @stable ICU 2.0 */ | 714 /** |
400 public synchronized void setMultiplier(int newValue) { | 715 * Sets a number that will be used to multiply all numbers prior to formatting
. For example, when |
401 if (newValue == 0) { | 716 * formatting percents, a multiplier of 100 can be used. |
| 717 * |
| 718 * <p>If a percent or permille sign is specified in the pattern, the multiplie
r is automatically |
| 719 * set to 100 or 1000, respectively. |
| 720 * |
| 721 * <p>If the number specified here is a power of 10, a more efficient code pat
h will be used. |
| 722 * |
| 723 * @param multiplier The number by which all numbers passed to {@link #format}
will be multiplied. |
| 724 * @throws IllegalArgumentException If the given multiplier is zero. |
| 725 * @category Multipliers |
| 726 * @stable ICU 2.0 |
| 727 */ |
| 728 public synchronized void setMultiplier(int multiplier) { |
| 729 if (multiplier == 0) { |
402 throw new IllegalArgumentException("Multiplier must be nonzero."); | 730 throw new IllegalArgumentException("Multiplier must be nonzero."); |
403 } | 731 } |
404 | 732 |
405 // Try to convert to a magnitude multiplier first | 733 // Try to convert to a magnitude multiplier first |
406 int delta = 0; | 734 int delta = 0; |
407 int value = newValue; | 735 int value = multiplier; |
408 while (newValue != 1) { | 736 while (multiplier != 1) { |
409 delta++; | 737 delta++; |
410 int temp = value / 10; | 738 int temp = value / 10; |
411 if (temp * 10 != value) { | 739 if (temp * 10 != value) { |
412 delta = -1; | 740 delta = -1; |
413 break; | 741 break; |
414 } | 742 } |
415 value = temp; | 743 value = temp; |
416 } | 744 } |
417 if (delta != -1) { | 745 if (delta != -1) { |
418 properties.setMagnitudeMultiplier(delta); | 746 properties.setMagnitudeMultiplier(delta); |
419 } else { | 747 } else { |
420 properties.setMultiplier(java.math.BigDecimal.valueOf(newValue)); | 748 properties.setMultiplier(java.math.BigDecimal.valueOf(multiplier)); |
421 } | 749 } |
422 refreshFormatter(); | 750 refreshFormatter(); |
423 } | 751 } |
424 | 752 |
425 /** @stable ICU 2.0 */ | 753 /** |
| 754 * @return The increment to which numbers are being rounded. |
| 755 * @see #setRoundingIncrement |
| 756 * @category Rounding |
| 757 * @stable ICU 2.0 |
| 758 */ |
426 public synchronized java.math.BigDecimal getRoundingIncrement() { | 759 public synchronized java.math.BigDecimal getRoundingIncrement() { |
427 return exportedProperties.getRoundingInterval(); | 760 return exportedProperties.getRoundingIncrement(); |
428 } | 761 } |
429 | 762 |
430 /** @stable ICU 2.0 */ | 763 /** |
431 public synchronized void setRoundingIncrement(java.math.BigDecimal newValue) { | 764 * <strong>Rounding and Digit Limits:</strong> Sets an increment, or interval,
to which numbers |
| 765 * are rounded. For example, a rounding increment of 0.05 will cause the numbe
r 1.23 to be rounded |
| 766 * to 1.25 in the default rounding mode. |
| 767 * |
| 768 * <p>The rounding increment can be specified via the pattern string: for exam
ple, the pattern |
| 769 * "#,##0.05" encodes a rounding increment of 0.05. |
| 770 * |
| 771 * <p>The rounding increment is applied <em>after</em> any multipliers might t
ake effect; for |
| 772 * example, in scientific notation or when {@link #setMultiplier} is used. |
| 773 * |
| 774 * <p>See {@link #setMaximumFractionDigits} and {@link #setMaximumSignificantD
igits} for two other |
| 775 * ways of specifying rounding strategies. |
| 776 * |
| 777 * @param increment The increment to which numbers are to be rounded. |
| 778 * @see #setRoundingMode |
| 779 * @see #setMaximumFractionDigits |
| 780 * @see #setMaximumSignificantDigits |
| 781 * @category Rounding |
| 782 * @stable ICU 2.0 |
| 783 */ |
| 784 public synchronized void setRoundingIncrement(java.math.BigDecimal increment)
{ |
432 // Backwards compatibility: ignore rounding increment if zero, | 785 // Backwards compatibility: ignore rounding increment if zero, |
433 // and instead set maximum fraction digits. | 786 // and instead set maximum fraction digits. |
434 if (newValue != null && newValue.compareTo(java.math.BigDecimal.ZERO) == 0)
{ | 787 if (increment != null && increment.compareTo(java.math.BigDecimal.ZERO) == 0
) { |
435 properties.setMaximumFractionDigits(Integer.MAX_VALUE); | 788 properties.setMaximumFractionDigits(Integer.MAX_VALUE); |
436 return; | 789 return; |
437 } | 790 } |
438 | 791 |
439 properties.setRoundingInterval(newValue); | 792 properties.setRoundingIncrement(increment); |
440 refreshFormatter(); | 793 refreshFormatter(); |
441 } | 794 } |
442 | 795 |
443 /** @stable ICU 3.6 */ | 796 /** |
444 public synchronized void setRoundingIncrement(BigDecimal newValue) { | 797 * <strong>Rounding and Digit Limits:</strong> Overload of {@link |
445 java.math.BigDecimal javaBigDecimal = (newValue == null) ? null : newValue.t
oBigDecimal(); | 798 * #setRoundingIncrement(java.math.BigDecimal)}. |
| 799 * |
| 800 * @param increment The increment to which numbers are to be rounded. |
| 801 * @see #setRoundingIncrement |
| 802 * @category Rounding |
| 803 * @stable ICU 3.6 |
| 804 */ |
| 805 public synchronized void setRoundingIncrement(BigDecimal increment) { |
| 806 java.math.BigDecimal javaBigDecimal = (increment == null) ? null : increment
.toBigDecimal(); |
446 setRoundingIncrement(javaBigDecimal); | 807 setRoundingIncrement(javaBigDecimal); |
447 } | 808 } |
448 | 809 |
449 /** @stable ICU 2.0 */ | 810 /** |
450 public synchronized void setRoundingIncrement(double newValue) { | 811 * <strong>Rounding and Digit Limits:</strong> Overload of {@link |
451 if (newValue == 0) { | 812 * #setRoundingIncrement(java.math.BigDecimal)}. |
| 813 * |
| 814 * @param increment The increment to which numbers are to be rounded. |
| 815 * @see #setRoundingIncrement |
| 816 * @category Rounding |
| 817 * @stable ICU 2.0 |
| 818 */ |
| 819 public synchronized void setRoundingIncrement(double increment) { |
| 820 if (increment == 0) { |
452 setRoundingIncrement((java.math.BigDecimal) null); | 821 setRoundingIncrement((java.math.BigDecimal) null); |
453 } else { | 822 } else { |
454 java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(newValu
e); | 823 java.math.BigDecimal javaBigDecimal = java.math.BigDecimal.valueOf(increme
nt); |
455 setRoundingIncrement(javaBigDecimal); | 824 setRoundingIncrement(javaBigDecimal); |
456 } | 825 } |
457 } | 826 } |
458 | 827 |
459 /** @stable ICU 2.0 */ | 828 /** |
| 829 * @return The rounding mode being used to round numbers. |
| 830 * @see #setRoundingMode |
| 831 * @category Rounding |
| 832 * @stable ICU 2.0 |
| 833 */ |
460 @Override | 834 @Override |
461 public synchronized int getRoundingMode() { | 835 public synchronized int getRoundingMode() { |
462 RoundingMode mode = exportedProperties.getRoundingMode(); | 836 RoundingMode mode = exportedProperties.getRoundingMode(); |
463 return (mode == null) ? 0 : mode.ordinal(); | 837 return (mode == null) ? 0 : mode.ordinal(); |
464 } | 838 } |
465 | 839 |
466 /** @stable ICU 2.0 */ | 840 /** |
| 841 * <strong>Rounding and Digit Limits:</strong> Sets the {@link RoundingMode} u
sed to round |
| 842 * numbers. The default rounding mode is HALF_EVEN, which rounds decimals to t
heir closest whole |
| 843 * number, and rounds to the closest even number if at the midpoint. |
| 844 * |
| 845 * <p>For more detail on rounding modes, see <a |
| 846 * href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes"
>the ICU User |
| 847 * Guide</a>. |
| 848 * |
| 849 * <p>For backwards compatibility, the rounding mode is specified as an int ar
gument, which can be |
| 850 * from either the constants in {@link BigDecimal} or the ordinal value of {@l
ink RoundingMode}. |
| 851 * The following two calls are functionally equivalent. |
| 852 * |
| 853 * <pre> |
| 854 * df.setRoundingMode(BigDecimal.ROUND_CEILING); |
| 855 * df.setRoundingMode(RoundingMode.CEILING.ordinal()); |
| 856 * </pre> |
| 857 * |
| 858 * @param roundingMode The integer constant rounding mode to use when formatti
ng numbers. |
| 859 * @category Rounding |
| 860 * @stable ICU 2.0 |
| 861 */ |
467 @Override | 862 @Override |
468 public synchronized void setRoundingMode(int roundingMode) { | 863 public synchronized void setRoundingMode(int roundingMode) { |
469 properties.setRoundingMode(RoundingMode.valueOf(roundingMode)); | 864 properties.setRoundingMode(RoundingMode.valueOf(roundingMode)); |
470 refreshFormatter(); | 865 refreshFormatter(); |
471 } | 866 } |
472 | 867 |
473 /** @stable ICU 2.0 */ | 868 /** |
474 public synchronized int getFormatWidth() { | 869 * @return The {@link java.math.MathContext} being used to round numbers. |
475 return exportedProperties.getPaddingWidth(); | 870 * @see #setMathContext |
476 } | 871 * @category Rounding |
477 | 872 * @stable ICU 4.2 |
478 /** @stable ICU 2.0 */ | 873 */ |
479 public synchronized void setFormatWidth(int width) { | 874 public synchronized java.math.MathContext getMathContext() { |
480 properties.setPaddingWidth(width); | 875 java.math.MathContext mathContext = exportedProperties.getMathContext(); |
481 refreshFormatter(); | 876 assert mathContext != null; |
482 } | 877 return mathContext; |
483 | 878 } |
484 /** @stable ICU 2.0 */ | 879 |
485 public synchronized char getPadCharacter() { | 880 /** |
486 CharSequence paddingString = exportedProperties.getPaddingString(); | 881 * <strong>Rounding and Digit Limits:</strong> Sets the {@link java.math.MathC
ontext} used to |
487 if (paddingString == null) { | 882 * round numbers. A "math context" encodes both a rounding mode and a number o
f significant |
488 return '.'; // TODO: Is this the correct behavior? | 883 * digits. |
489 } else { | 884 * |
490 return paddingString.charAt(0); | 885 * <p>This method is provided for users who require their output to conform to
a standard math |
491 } | 886 * context. <strong>Most users should call {@link #setRoundingMode} and/or {@l
ink |
492 } | 887 * #setMaximumSignificantDigits} instead of this method.</strong> |
493 | 888 * |
494 /** @stable ICU 2.0 */ | 889 * @param mathContext The MathContext to use when rounding numbers. |
495 public synchronized void setPadCharacter(char padChar) { | 890 * @see java.math.MathContext |
496 properties.setPaddingString(Character.toString(padChar)); | 891 * @category Rounding |
497 refreshFormatter(); | 892 * @stable ICU 4.2 |
498 } | 893 */ |
499 | 894 public synchronized void setMathContext(java.math.MathContext mathContext) { |
500 /** @stable ICU 2.0 */ | 895 properties.setMathContext(mathContext); |
501 public synchronized int getPadPosition() { | 896 refreshFormatter(); |
502 PaddingLocation loc = exportedProperties.getPaddingLocation(); | 897 } |
503 return (loc == null) ? PAD_BEFORE_PREFIX : loc.toOld(); | 898 |
504 } | 899 // Remember the ICU math context form in order to be able to return it from th
e API. |
505 | 900 // NOTE: This value is not serialized. (should it be?) |
506 /** @stable ICU 2.0 */ | 901 private transient int icuMathContextForm = MathContext.PLAIN; |
507 public synchronized void setPadPosition(int padPos) { | 902 |
508 properties.setPaddingLocation(PaddingLocation.fromOld(padPos)); | 903 /** |
509 refreshFormatter(); | 904 * @return The {@link com.ibm.icu.math.MathContext} being used to round number
s. |
510 } | 905 * @see #setMathContext |
511 | 906 * @category Rounding |
512 /** @stable ICU 2.0 */ | 907 * @stable ICU 4.2 |
513 public synchronized boolean isScientificNotation() { | 908 */ |
514 return ScientificFormat.useScientificNotation(properties); | |
515 } | |
516 | |
517 /** @stable ICU 2.0 */ | |
518 public synchronized void setScientificNotation(boolean useScientific) { | |
519 if (useScientific) { | |
520 properties.setExponentDigits(1); | |
521 } else { | |
522 properties.setExponentDigits(Properties.DEFAULT_EXPONENT_DIGITS); | |
523 } | |
524 refreshFormatter(); | |
525 } | |
526 | |
527 /** @stable ICU 2.0 */ | |
528 public synchronized byte getMinimumExponentDigits() { | |
529 return (byte) exportedProperties.getExponentDigits(); | |
530 } | |
531 | |
532 /** @stable ICU 2.0 */ | |
533 public synchronized void setMinimumExponentDigits(byte minExpDig) { | |
534 properties.setExponentDigits(minExpDig); | |
535 refreshFormatter(); | |
536 } | |
537 | |
538 /** @stable ICU 2.0 */ | |
539 public synchronized boolean isExponentSignAlwaysShown() { | |
540 return exportedProperties.getExponentShowPlusSign(); | |
541 } | |
542 | |
543 /** @stable ICU 2.0 */ | |
544 public synchronized void setExponentSignAlwaysShown(boolean expSignAlways) { | |
545 properties.setExponentShowPlusSign(expSignAlways); | |
546 refreshFormatter(); | |
547 } | |
548 | |
549 /** @stable ICU 2.0 */ | |
550 public synchronized int getGroupingSize() { | |
551 return exportedProperties.getGroupingSize(); | |
552 } | |
553 | |
554 /** @stable ICU 2.0 */ | |
555 public synchronized void setGroupingSize(int newValue) { | |
556 properties.setGroupingSize(newValue); | |
557 refreshFormatter(); | |
558 } | |
559 | |
560 /** @stable ICU 2.0 */ | |
561 public synchronized int getSecondaryGroupingSize() { | |
562 return exportedProperties.getSecondaryGroupingSize(); | |
563 } | |
564 | |
565 /** @stable ICU 2.0 */ | |
566 public synchronized void setSecondaryGroupingSize(int newValue) { | |
567 properties.setSecondaryGroupingSize(newValue); | |
568 refreshFormatter(); | |
569 } | |
570 | |
571 /** @stable ICU 2.0 */ | |
572 @Override | |
573 public synchronized boolean isGroupingUsed() { | |
574 return PositiveDecimalFormat.useGrouping(properties); | |
575 } | |
576 | |
577 /** @stable ICU 2.0 */ | |
578 @Override | |
579 public synchronized void setGroupingUsed(boolean newValue) { | |
580 if (newValue) { | |
581 // Set to a reasonable default value | |
582 properties.setGroupingSize(3); | |
583 } else { | |
584 properties.setGroupingSize(Properties.DEFAULT_GROUPING_SIZE); | |
585 properties.setSecondaryGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_
SIZE); | |
586 } | |
587 refreshFormatter(); | |
588 } | |
589 | |
590 /** Remember the ICU math context form in order to be able to return it from t
he API. */ | |
591 private int icuMathContextForm = MathContext.PLAIN; | |
592 | |
593 /** @stable ICU 4.2 */ | |
594 public synchronized MathContext getMathContextICU() { | 909 public synchronized MathContext getMathContextICU() { |
595 java.math.MathContext mathContext = getMathContext(); | 910 java.math.MathContext mathContext = getMathContext(); |
596 return new MathContext( | 911 return new MathContext( |
597 mathContext.getPrecision(), | 912 mathContext.getPrecision(), |
598 icuMathContextForm, | 913 icuMathContextForm, |
599 false, | 914 false, |
600 mathContext.getRoundingMode().ordinal()); | 915 mathContext.getRoundingMode().ordinal()); |
601 } | 916 } |
602 | 917 |
603 /** @stable ICU 4.2 */ | 918 /** |
604 public synchronized void setMathContextICU(MathContext newValue) { | 919 * <strong>Rounding and Digit Limits:</strong> Overload of {@link #setMathCont
ext} for {@link |
605 icuMathContextForm = newValue.getForm(); | 920 * com.ibm.icu.math.MathContext}. |
| 921 * |
| 922 * @param mathContextICU The MathContext to use when rounding numbers. |
| 923 * @see #setMathContext(java.math.MathContext) |
| 924 * @category Rounding |
| 925 * @stable ICU 4.2 |
| 926 */ |
| 927 public synchronized void setMathContextICU(MathContext mathContextICU) { |
| 928 icuMathContextForm = mathContextICU.getForm(); |
606 java.math.MathContext mathContext; | 929 java.math.MathContext mathContext; |
607 if (newValue.getLostDigits()) { | 930 if (mathContextICU.getLostDigits()) { |
608 // The getLostDigits() feature in ICU MathContext means "throw an Arithmet
icException if | 931 // The getLostDigits() feature in ICU MathContext means "throw an Arithmet
icException if |
609 // rounding causes digits to be lost". That feature is called RoundingMode
.UNNECESSARY in | 932 // rounding causes digits to be lost". That feature is called RoundingMode
.UNNECESSARY in |
610 // Java MathContext. | 933 // Java MathContext. |
611 mathContext = new java.math.MathContext( | 934 mathContext = new java.math.MathContext(mathContextICU.getDigits(), Roundi
ngMode.UNNECESSARY); |
612 newValue.getDigits(), | |
613 RoundingMode.UNNECESSARY); | |
614 } else { | 935 } else { |
615 mathContext = new java.math.MathContext( | 936 mathContext = |
616 newValue.getDigits(), | 937 new java.math.MathContext( |
617 RoundingMode.valueOf(newValue.getRoundingMode())); | 938 mathContextICU.getDigits(), RoundingMode.valueOf(mathContextICU.ge
tRoundingMode())); |
618 } | 939 } |
619 setMathContext(mathContext); | 940 setMathContext(mathContext); |
620 } | 941 } |
621 | 942 |
622 /** @stable ICU 4.2 */ | 943 /** |
623 public synchronized java.math.MathContext getMathContext() { | 944 * @return The effective minimum number of digits before the decimal separator
. |
624 java.math.MathContext mathContext = exportedProperties.getMathContext(); | 945 * @see #setMinimumIntegerDigits |
625 assert mathContext != null; | 946 * @category Rounding |
626 return mathContext; | 947 * @stable ICU 2.0 |
627 } | 948 */ |
628 | 949 @Override |
629 /** @stable ICU 4.2 */ | 950 public synchronized int getMinimumIntegerDigits() { |
630 public synchronized void setMathContext(java.math.MathContext newValue) { | 951 return exportedProperties.getMinimumIntegerDigits(); |
631 properties.setMathContext(newValue); | 952 } |
632 refreshFormatter(); | 953 |
633 } | 954 /** |
634 | 955 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digi
ts to display before |
635 /** @stable ICU 54 */ | 956 * the decimal separator. If the number has fewer than this many digits, the n
umber is padded with |
636 public synchronized void setDecimalPatternMatchRequired(boolean value) { | 957 * zeros. |
637 properties.setDecimalPatternMatchRequired(value); | 958 * |
638 refreshFormatter(); | 959 * <p>For example, if minimum integer digits is 3, the number 12.3 will be pri
nted as "001.23". |
639 } | 960 * |
640 | 961 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
641 /** @stable ICU 54 */ | 962 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
642 public synchronized boolean isDecimalPatternMatchRequired() { | 963 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
643 return properties.getDecimalPatternMatchRequired(); | 964 * pattern except in scientific notation. |
644 } | 965 * |
645 | 966 * @param value The minimum number of digits before the decimal separator. |
646 /** @stable ICU 2.0 */ | 967 * @category Rounding |
647 public synchronized boolean isDecimalSeparatorAlwaysShown() { | 968 * @stable ICU 2.0 |
648 return exportedProperties.getAlwaysShowDecimal(); | 969 */ |
649 } | 970 @Override |
650 | 971 public synchronized void setMinimumIntegerDigits(int value) { |
651 /** @stable ICU 2.0 */ | 972 properties.setMinimumIntegerDigits(value); |
652 public synchronized void setDecimalSeparatorAlwaysShown(boolean newValue) { | 973 refreshFormatter(); |
653 properties.setAlwaysShowDecimal(newValue); | 974 } |
654 refreshFormatter(); | 975 |
655 } | 976 /** |
656 | 977 * @return The effective maximum number of digits before the decimal separator
. |
657 /** @stable ICU 2.0 */ | 978 * @see #setMaximumIntegerDigits |
| 979 * @category Rounding |
| 980 * @stable ICU 2.0 |
| 981 */ |
658 @Override | 982 @Override |
659 public synchronized int getMaximumIntegerDigits() { | 983 public synchronized int getMaximumIntegerDigits() { |
660 return exportedProperties.getMaximumIntegerDigits(); | 984 return exportedProperties.getMaximumIntegerDigits(); |
661 } | 985 } |
662 | 986 |
663 /** @stable ICU 2.0 */ | 987 /** |
664 @Override | 988 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digi
ts to display before |
665 public synchronized int getMinimumIntegerDigits() { | 989 * the decimal separator. If the number has more than this many digits, the nu
mber is truncated. |
666 return exportedProperties.getMinimumIntegerDigits(); | 990 * |
667 } | 991 * <p>For example, if maximum integer digits is 3, the number 12345 will be pr
inted as "345". |
668 | 992 * |
669 /** @stable ICU 2.0 */ | 993 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
670 @Override | 994 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
671 public synchronized void setMaximumIntegerDigits(int newValue) { | 995 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
672 properties.setMaximumIntegerDigits(newValue); | 996 * pattern except in scientific notation. |
673 refreshFormatter(); | 997 * |
674 } | 998 * @param value The maximum number of digits before the decimal separator. |
675 | 999 * @category Rounding |
676 /** @stable ICU 2.0 */ | 1000 * @stable ICU 2.0 |
677 @Override | 1001 */ |
678 public synchronized void setMinimumIntegerDigits(int newValue) { | 1002 @Override |
679 properties.setMinimumIntegerDigits(newValue); | 1003 public synchronized void setMaximumIntegerDigits(int value) { |
680 refreshFormatter(); | 1004 properties.setMaximumIntegerDigits(value); |
681 } | 1005 refreshFormatter(); |
682 | 1006 } |
683 /** @stable ICU 2.0 */ | 1007 |
| 1008 /** |
| 1009 * @return The effective minimum number of integer digits after the decimal se
parator. |
| 1010 * @see #setMaximumIntegerDigits |
| 1011 * @category Rounding |
| 1012 * @stable ICU 2.0 |
| 1013 */ |
| 1014 @Override |
| 1015 public synchronized int getMinimumFractionDigits() { |
| 1016 return exportedProperties.getMinimumFractionDigits(); |
| 1017 } |
| 1018 |
| 1019 /** |
| 1020 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of digi
ts to display after |
| 1021 * the decimal separator. If the number has fewer than this many digits, the n
umber is padded with |
| 1022 * zeros. |
| 1023 * |
| 1024 * <p>For example, if minimum fraction digits is 2, the number 123.4 will be p
rinted as "123.40". |
| 1025 * |
| 1026 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
| 1027 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
| 1028 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
| 1029 * pattern except in scientific notation. |
| 1030 * |
| 1031 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumSignificantDigit
s} for two other |
| 1032 * ways of specifying rounding strategies. |
| 1033 * |
| 1034 * @param value The minimum number of integer digits after the decimal separat
or. |
| 1035 * @see #setRoundingMode |
| 1036 * @see #setRoundingIncrement |
| 1037 * @see #setMaximumSignificantDigits |
| 1038 * @category Rounding |
| 1039 * @stable ICU 2.0 |
| 1040 */ |
| 1041 @Override |
| 1042 public synchronized void setMinimumFractionDigits(int value) { |
| 1043 properties.setMinimumFractionDigits(value); |
| 1044 refreshFormatter(); |
| 1045 } |
| 1046 |
| 1047 /** |
| 1048 * @return The effective maximum number of integer digits after the decimal se
parator. |
| 1049 * @see #setMaximumIntegerDigits |
| 1050 * @category Rounding |
| 1051 * @stable ICU 2.0 |
| 1052 */ |
684 @Override | 1053 @Override |
685 public synchronized int getMaximumFractionDigits() { | 1054 public synchronized int getMaximumFractionDigits() { |
686 return exportedProperties.getMaximumFractionDigits(); | 1055 return exportedProperties.getMaximumFractionDigits(); |
687 } | 1056 } |
688 | 1057 |
689 /** @stable ICU 2.0 */ | 1058 /** |
690 @Override | 1059 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of digi
ts to display after |
691 public synchronized int getMinimumFractionDigits() { | 1060 * the decimal separator. If the number has more than this many digits, the nu
mber is rounded |
692 return exportedProperties.getMinimumFractionDigits(); | 1061 * according to the rounding mode. |
693 } | 1062 * |
694 | 1063 * <p>For example, if maximum fraction digits is 2, the number 123.456 will be
printed as |
695 /** @stable ICU 2.0 */ | 1064 * "123.46". |
696 @Override | 1065 * |
697 public synchronized void setMaximumFractionDigits(int newValue) { | 1066 * <p>Minimum integer and minimum and maximum fraction digits can be specified
via the pattern |
698 properties.setMaximumFractionDigits(newValue); | 1067 * string. For example, "#,#00.00#" has 2 minimum integer digits, 2 minimum fr
action digits, and 3 |
699 refreshFormatter(); | 1068 * maximum fraction digits. Note that it is not possible to specify maximium i
nteger digits in the |
700 } | 1069 * pattern except in scientific notation. |
701 | 1070 * |
702 /** @stable ICU 2.0 */ | 1071 * @param value The maximum number of integer digits after the decimal separat
or. |
703 @Override | 1072 * @see #setRoundingMode |
704 public synchronized void setMinimumFractionDigits(int newValue) { | 1073 * @category Rounding |
705 properties.setMinimumFractionDigits(newValue); | 1074 * @stable ICU 2.0 |
706 refreshFormatter(); | 1075 */ |
707 } | 1076 @Override |
708 | 1077 public synchronized void setMaximumFractionDigits(int value) { |
709 /** @stable ICU 3.0 */ | 1078 properties.setMaximumFractionDigits(value); |
710 public synchronized int getMinimumSignificantDigits() { | 1079 refreshFormatter(); |
711 return exportedProperties.getMinimumSignificantDigits(); | 1080 } |
712 } | 1081 |
713 | 1082 /** |
714 /** @stable ICU 3.0 */ | 1083 * @return Whether significant digits are being used in rounding. |
715 public synchronized int getMaximumSignificantDigits() { | 1084 * @see #setSignificantDigitsUsed |
716 return exportedProperties.getMaximumSignificantDigits(); | 1085 * @category Rounding |
717 } | 1086 * @stable ICU 3.0 |
718 | 1087 */ |
719 /** @stable ICU 3.0 */ | |
720 public synchronized void setMinimumSignificantDigits(int min) { | |
721 properties.setMinimumSignificantDigits(min); | |
722 refreshFormatter(); | |
723 } | |
724 | |
725 /** @stable ICU 3.0 */ | |
726 public synchronized void setMaximumSignificantDigits(int max) { | |
727 properties.setMaximumSignificantDigits(max); | |
728 refreshFormatter(); | |
729 } | |
730 | |
731 /** @stable ICU 3.0 */ | |
732 public synchronized boolean areSignificantDigitsUsed() { | 1088 public synchronized boolean areSignificantDigitsUsed() { |
733 return SignificantDigitsRounder.useSignificantDigits(properties); | 1089 return SignificantDigitsRounder.useSignificantDigits(properties); |
734 } | 1090 } |
735 | 1091 |
736 /** @stable ICU 3.0 */ | 1092 /** |
| 1093 * <strong>Rounding and Digit Limits:</strong> Sets whether significant digits
are to be used in |
| 1094 * rounding. |
| 1095 * |
| 1096 * <p>Calling <code>df.setSignificantDigitsUsed(true)</code> is functionally e
quivalent to: |
| 1097 * |
| 1098 * <pre> |
| 1099 * df.setMinimumSignificantDigits(1); |
| 1100 * df.setMaximumSignificantDigits(6); |
| 1101 * </pre> |
| 1102 * |
| 1103 * @param useSignificantDigits true to enable significant digit rounding; fals
e to disable it. |
| 1104 * @category Rounding |
| 1105 * @stable ICU 3.0 |
| 1106 */ |
737 public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits
) { | 1107 public synchronized void setSignificantDigitsUsed(boolean useSignificantDigits
) { |
738 if (useSignificantDigits) { | 1108 if (useSignificantDigits) { |
739 // These are the default values from the old implementation. | 1109 // These are the default values from the old implementation. |
740 properties.setMinimumSignificantDigits(1); | 1110 properties.setMinimumSignificantDigits(1); |
741 properties.setMaximumSignificantDigits(6); | 1111 properties.setMaximumSignificantDigits(6); |
742 } else { | 1112 } else { |
743 properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFIC
ANT_DIGITS); | 1113 properties.setMinimumSignificantDigits(Properties.DEFAULT_MINIMUM_SIGNIFIC
ANT_DIGITS); |
744 properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFIC
ANT_DIGITS); | 1114 properties.setMaximumSignificantDigits(Properties.DEFAULT_MAXIMUM_SIGNIFIC
ANT_DIGITS); |
| 1115 properties.setSignificantDigitsMode(null); |
745 } | 1116 } |
746 refreshFormatter(); | 1117 refreshFormatter(); |
747 } | 1118 } |
748 | 1119 |
| 1120 /** |
| 1121 * @return The effective minimum number of significant digits displayed. |
| 1122 * @see #setMinimumSignificantDigits |
| 1123 * @category Rounding |
| 1124 * @stable ICU 3.0 |
| 1125 */ |
| 1126 public synchronized int getMinimumSignificantDigits() { |
| 1127 return exportedProperties.getMinimumSignificantDigits(); |
| 1128 } |
| 1129 |
| 1130 /** |
| 1131 * <strong>Rounding and Digit Limits:</strong> Sets the minimum number of sign
ificant digits to be |
| 1132 * displayed. If the number of significant digits is less than this value, the
number will be |
| 1133 * padded with zeros as necessary. |
| 1134 * |
| 1135 * <p>For example, if minimum significant digits is 3 and the number is 1.2, t
he number will be |
| 1136 * printed as "1.20". |
| 1137 * |
| 1138 * @param value The minimum number of significant digits to display. |
| 1139 * @see #setSignificantDigitsMode |
| 1140 * @category Rounding |
| 1141 * @stable ICU 3.0 |
| 1142 */ |
| 1143 public synchronized void setMinimumSignificantDigits(int value) { |
| 1144 properties.setMinimumSignificantDigits(value); |
| 1145 refreshFormatter(); |
| 1146 } |
| 1147 |
| 1148 /** |
| 1149 * @return The effective maximum number of significant digits displayed. |
| 1150 * @see #setMaximumSignificantDigits |
| 1151 * @category Rounding |
| 1152 * @stable ICU 3.0 |
| 1153 */ |
| 1154 public synchronized int getMaximumSignificantDigits() { |
| 1155 return exportedProperties.getMaximumSignificantDigits(); |
| 1156 } |
| 1157 |
| 1158 /** |
| 1159 * <strong>Rounding and Digit Limits:</strong> Sets the maximum number of sign
ificant digits to be |
| 1160 * displayed. If the number of significant digits in the number exceeds this v
alue, the number |
| 1161 * will be rounded according to the current rounding mode. |
| 1162 * |
| 1163 * <p>For example, if maximum significant digits is 3 and the number is 12345,
the number will be |
| 1164 * printed as "12300". |
| 1165 * |
| 1166 * <p>See {@link #setRoundingIncrement} and {@link #setMaximumFractionDigits}
for two other ways |
| 1167 * of specifying rounding strategies. |
| 1168 * |
| 1169 * @param value The maximum number of significant digits to display. |
| 1170 * @see #setRoundingMode |
| 1171 * @see #setRoundingIncrement |
| 1172 * @see #setMaximumFractionDigits |
| 1173 * @see #setSignificantDigitsMode |
| 1174 * @category Rounding |
| 1175 * @stable ICU 3.0 |
| 1176 */ |
| 1177 public synchronized void setMaximumSignificantDigits(int value) { |
| 1178 properties.setMaximumSignificantDigits(value); |
| 1179 refreshFormatter(); |
| 1180 } |
| 1181 |
| 1182 /** |
| 1183 * @return The current significant digits mode. |
| 1184 * @see #setSignificantDigitsMode |
| 1185 * @category Rounding |
| 1186 * @internal |
| 1187 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1188 */ |
| 1189 @Deprecated |
| 1190 public synchronized SignificantDigitsMode getSignificantDigitsMode() { |
| 1191 return exportedProperties.getSignificantDigitsMode(); |
| 1192 } |
| 1193 |
| 1194 /** |
| 1195 * <strong>Rounding and Digit Limits:</strong> Sets the strategy used for reso
lving |
| 1196 * minimum/maximum significant digits when minimum/maximum integer and/or frac
tion digits are |
| 1197 * specified. There are three modes: |
| 1198 * |
| 1199 * <ul> |
| 1200 * <li>Mode A: OVERRIDE_MAXIMUM_FRACTION. This is the default. Settings in m
aximum fraction are |
| 1201 * ignored. |
| 1202 * <li>Mode B: RESPECT_MAXIMUM_FRACTION. Round to maximum fraction even if d
oing so will prevent |
| 1203 * minimum significant from being respected. |
| 1204 * <li>Mode C: ENSURE_MINIMUM_SIGNIFICANT. Respect maximum fraction, but alw
ays ensure that |
| 1205 * minimum significant digits are shown. |
| 1206 * </ul> |
| 1207 * |
| 1208 * <p>The following table illustrates the difference. Below, minFrac=1, maxFra
c=2, minSig=3, and |
| 1209 * maxSig=4: |
| 1210 * |
| 1211 * <pre> |
| 1212 * Mode A | Mode B | Mode C |
| 1213 * ---------+----------+---------- |
| 1214 * 12340.0 | 12340.0 | 12340.0 |
| 1215 * 1234.0 | 1234.0 | 1234.0 |
| 1216 * 123.4 | 123.4 | 123.4 |
| 1217 * 12.34 | 12.34 | 12.34 |
| 1218 * 1.234 | 1.23 | 1.23 |
| 1219 * 0.1234 | 0.12 | 0.123 |
| 1220 * 0.01234 | 0.01 | 0.0123 |
| 1221 * 0.001234 | 0.00 | 0.00123 |
| 1222 * </pre> |
| 1223 * |
| 1224 * @param mode The significant digits mode to use. |
| 1225 * @category Rounding |
| 1226 * @internal |
| 1227 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1228 */ |
| 1229 @Deprecated |
| 1230 public synchronized void setSignificantDigitsMode(SignificantDigitsMode mode)
{ |
| 1231 properties.setSignificantDigitsMode(mode); |
| 1232 refreshFormatter(); |
| 1233 } |
| 1234 |
| 1235 /** |
| 1236 * @return The minimum number of characters in formatted output. |
| 1237 * @see #setFormatWidth |
| 1238 * @category Padding |
| 1239 * @stable ICU 2.0 |
| 1240 */ |
| 1241 public synchronized int getFormatWidth() { |
| 1242 return exportedProperties.getFormatWidth(); |
| 1243 } |
| 1244 |
| 1245 /** |
| 1246 * <strong>Padding:</strong> Sets the minimum width of the string output by th
e formatting |
| 1247 * pipeline. For example, if padding is enabled and paddingWidth is set to 6,
formatting the |
| 1248 * number "3.14159" with the pattern "0.00" will result in "··3.14" if '·' is
your padding string. |
| 1249 * |
| 1250 * <p>If the number is longer than your padding width, the number will display
as if no padding |
| 1251 * width had been specified, which may result in strings longer than the paddi
ng width. |
| 1252 * |
| 1253 * <p>Padding can be specified in the pattern string using the '*' symbol. For
example, the format |
| 1254 * "*x######0" has a format width of 7 and a pad character of 'x'. |
| 1255 * |
| 1256 * <p>Padding is currently counted in UTF-16 code units; see <a |
| 1257 * href="http://bugs.icu-project.org/trac/ticket/13034">ticket #13034</a> for
more information. |
| 1258 * |
| 1259 * @param width The minimum number of characters in the output. |
| 1260 * @see #setPadCharacter |
| 1261 * @see #setPadPosition |
| 1262 * @category Padding |
| 1263 * @stable ICU 2.0 |
| 1264 */ |
| 1265 public synchronized void setFormatWidth(int width) { |
| 1266 properties.setFormatWidth(width); |
| 1267 refreshFormatter(); |
| 1268 } |
| 1269 |
| 1270 /** |
| 1271 * @return The character used for padding. |
| 1272 * @see #setPadCharacter |
| 1273 * @category Padding |
| 1274 * @stable ICU 2.0 |
| 1275 */ |
| 1276 public synchronized char getPadCharacter() { |
| 1277 CharSequence paddingString = exportedProperties.getPadString(); |
| 1278 if (paddingString == null) { |
| 1279 return '.'; // TODO: Is this the correct behavior? |
| 1280 } else { |
| 1281 return paddingString.charAt(0); |
| 1282 } |
| 1283 } |
| 1284 |
| 1285 /** |
| 1286 * <strong>Padding:</strong> Sets the character used to pad numbers that are n
arrower than the |
| 1287 * width specified in {@link #setFormatWidth}. |
| 1288 * |
| 1289 * <p>In the pattern string, the padding character is the token that follows '
*' before or after |
| 1290 * the prefix or suffix. |
| 1291 * |
| 1292 * @param padChar The character used for padding. |
| 1293 * @see #setFormatWidth |
| 1294 * @category Padding |
| 1295 * @stable ICU 2.0 |
| 1296 */ |
| 1297 public synchronized void setPadCharacter(char padChar) { |
| 1298 properties.setPadString(Character.toString(padChar)); |
| 1299 refreshFormatter(); |
| 1300 } |
| 1301 |
| 1302 /** |
| 1303 * @return The position used for padding. |
| 1304 * @see #setPadPosition |
| 1305 * @category Padding |
| 1306 * @stable ICU 2.0 |
| 1307 */ |
| 1308 public synchronized int getPadPosition() { |
| 1309 PadPosition loc = exportedProperties.getPadPosition(); |
| 1310 return (loc == null) ? PAD_BEFORE_PREFIX : loc.toOld(); |
| 1311 } |
| 1312 |
| 1313 /** |
| 1314 * <strong>Padding:</strong> Sets the position where to insert the pad charact
er when narrower |
| 1315 * than the width specified in {@link #setFormatWidth}. For example, consider
the pattern "P123S" |
| 1316 * with padding width 8 and padding char "*". The four positions are: |
| 1317 * |
| 1318 * <ul> |
| 1319 * <li>{@link DecimalFormat#PAD_BEFORE_PREFIX} ⇒ "***P123S" |
| 1320 * <li>{@link DecimalFormat#PAD_AFTER_PREFIX} ⇒ "P***123S" |
| 1321 * <li>{@link DecimalFormat#PAD_BEFORE_SUFFIX} ⇒ "P123***S" |
| 1322 * <li>{@link DecimalFormat#PAD_AFTER_SUFFIX} ⇒ "P123S***" |
| 1323 * </ul> |
| 1324 * |
| 1325 * @param padPos The position used for padding. |
| 1326 * @see #setFormatWidth |
| 1327 * @category Padding |
| 1328 * @stable ICU 2.0 |
| 1329 */ |
| 1330 public synchronized void setPadPosition(int padPos) { |
| 1331 properties.setPadPosition(PadPosition.fromOld(padPos)); |
| 1332 refreshFormatter(); |
| 1333 } |
| 1334 |
| 1335 /** |
| 1336 * @return Whether scientific (exponential) notation is enabled on this format
ter. |
| 1337 * @see #setScientificNotation |
| 1338 * @category ScientificNotation |
| 1339 * @stable ICU 2.0 |
| 1340 */ |
| 1341 public synchronized boolean isScientificNotation() { |
| 1342 return ScientificFormat.useScientificNotation(properties); |
| 1343 } |
| 1344 |
| 1345 /** |
| 1346 * <strong>Scientific Notation:</strong> Sets whether this formatter should pr
int in scientific |
| 1347 * (exponential) notation. For example, if scientific notation is enabled, the
number 123000 will |
| 1348 * be printed as "1.23E5" in locale <em>en-US</em>. A locale-specific symbol i
s used as the |
| 1349 * exponent separator. |
| 1350 * |
| 1351 * <p>Calling <code>df.setScientificNotation(true)</code> is functionally equi
valent to calling |
| 1352 * <code>df.setMinimumExponentDigits(1)</code>. |
| 1353 * |
| 1354 * @param useScientific true to enable scientific notation; false to disable i
t. |
| 1355 * @see #setMinimumExponentDigits |
| 1356 * @category ScientificNotation |
| 1357 * @stable ICU 2.0 |
| 1358 */ |
| 1359 public synchronized void setScientificNotation(boolean useScientific) { |
| 1360 if (useScientific) { |
| 1361 properties.setMinimumExponentDigits(1); |
| 1362 } else { |
| 1363 properties.setMinimumExponentDigits(Properties.DEFAULT_MINIMUM_EXPONENT_DI
GITS); |
| 1364 } |
| 1365 refreshFormatter(); |
| 1366 } |
| 1367 |
| 1368 /** |
| 1369 * @return The minimum number of digits printed in the exponent in scientific
notation. |
| 1370 * @see #setMinimumExponentDigits |
| 1371 * @category ScientificNotation |
| 1372 * @stable ICU 2.0 |
| 1373 */ |
| 1374 public synchronized byte getMinimumExponentDigits() { |
| 1375 return (byte) exportedProperties.getMinimumExponentDigits(); |
| 1376 } |
| 1377 |
| 1378 /** |
| 1379 * <strong>Scientific Notation:</strong> Sets the minimum number of digits to
be printed in the |
| 1380 * exponent. For example, if minimum exponent digits is 3, the number 123000 w
ill be printed as |
| 1381 * "1.23E005". |
| 1382 * |
| 1383 * <p>This setting corresponds to the number of zeros after the 'E' in a patte
rn string such as |
| 1384 * "0.00E000". |
| 1385 * |
| 1386 * @param minExpDig The minimum number of digits in the exponent. |
| 1387 * @category ScientificNotation |
| 1388 * @stable ICU 2.0 |
| 1389 */ |
| 1390 public synchronized void setMinimumExponentDigits(byte minExpDig) { |
| 1391 properties.setMinimumExponentDigits(minExpDig); |
| 1392 refreshFormatter(); |
| 1393 } |
| 1394 |
| 1395 /** |
| 1396 * @return Whether the sign (plus or minus) is always printed in scientific no
tation. |
| 1397 * @see #setExponentSignAlwaysShown |
| 1398 * @category ScientificNotation |
| 1399 * @stable ICU 2.0 |
| 1400 */ |
| 1401 public synchronized boolean isExponentSignAlwaysShown() { |
| 1402 return exportedProperties.getExponentSignAlwaysShown(); |
| 1403 } |
| 1404 |
| 1405 /** |
| 1406 * <strong>Scientific Notation:</strong> Sets whether the sign (plus or minus)
is always to be |
| 1407 * shown in the exponent in scientific notation. For example, if this setting
is enabled, the |
| 1408 * number 123000 will be printed as "1.23E+5" in locale <em>en-US</em>. The nu
mber 0.0000123 will |
| 1409 * always be printed as "1.23E-5" in locale <em>en-US</em> whether or not this
setting is enabled. |
| 1410 * |
| 1411 * <p>This setting corresponds to the '+' in a pattern such as "0.00E+0". |
| 1412 * |
| 1413 * @param expSignAlways true to always shown the sign in the exponent; false t
o show it for |
| 1414 * negatives but not positives. |
| 1415 * @category ScientificNotation |
| 1416 * @stable ICU 2.0 |
| 1417 */ |
| 1418 public synchronized void setExponentSignAlwaysShown(boolean expSignAlways) { |
| 1419 properties.setExponentSignAlwaysShown(expSignAlways); |
| 1420 refreshFormatter(); |
| 1421 } |
| 1422 |
| 1423 /** |
| 1424 * @return Whether or not grouping separators are to be printed in the output. |
| 1425 * @see #setGroupingUsed |
| 1426 * @category Separators |
| 1427 * @stable ICU 2.0 |
| 1428 */ |
| 1429 @Override |
| 1430 public synchronized boolean isGroupingUsed() { |
| 1431 return PositiveDecimalFormat.useGrouping(properties); |
| 1432 } |
| 1433 |
| 1434 /** |
| 1435 * <strong>Grouping:</strong> Sets whether grouping is to be used when formatt
ing numbers. |
| 1436 * Grouping means whether the thousands, millions, billions, and larger powers
of ten should be |
| 1437 * separated by a grouping separator (a comma in <em>en-US</em>). |
| 1438 * |
| 1439 * <p>For example, if grouping is enabled, 12345 will be printed as "12,345" i
n <em>en-US</em>. If |
| 1440 * grouping were disabled, it would instead be printed as simply "12345". |
| 1441 * |
| 1442 * <p>Calling <code>df.setGroupingUsed(true)</code> is functionally equivalent
to setting grouping |
| 1443 * size to 3, as in <code>df.setGroupingSize(3)</code>. |
| 1444 * |
| 1445 * @param enabled true to enable grouping separators; false to disable them. |
| 1446 * @see #setGroupingSize |
| 1447 * @see #setSecondaryGroupingSize |
| 1448 * @category Separators |
| 1449 * @stable ICU 2.0 |
| 1450 */ |
| 1451 @Override |
| 1452 public synchronized void setGroupingUsed(boolean enabled) { |
| 1453 if (enabled) { |
| 1454 // Set to a reasonable default value |
| 1455 properties.setGroupingSize(3); |
| 1456 } else { |
| 1457 properties.setGroupingSize(Properties.DEFAULT_GROUPING_SIZE); |
| 1458 properties.setSecondaryGroupingSize(Properties.DEFAULT_SECONDARY_GROUPING_
SIZE); |
| 1459 } |
| 1460 refreshFormatter(); |
| 1461 } |
| 1462 |
| 1463 /** |
| 1464 * @return The primary grouping size in use. |
| 1465 * @see #setGroupingSize |
| 1466 * @category Separators |
| 1467 * @stable ICU 2.0 |
| 1468 */ |
| 1469 public synchronized int getGroupingSize() { |
| 1470 return exportedProperties.getGroupingSize(); |
| 1471 } |
| 1472 |
| 1473 /** |
| 1474 * <strong>Grouping:</strong> Sets the primary grouping size (distance between
grouping |
| 1475 * separators) used when formatting large numbers. For most locales, this defa
ults to 3: the |
| 1476 * number of digits between the ones and thousands place, between thousands an
d millions, and so |
| 1477 * forth. |
| 1478 * |
| 1479 * <p>For example, with a grouping size of 3, the number 1234567 will be forma
tted as "1,234,567". |
| 1480 * |
| 1481 * <p>Grouping size can also be specified in the pattern: for example, "#,##0"
corresponds to a |
| 1482 * grouping size of 3. |
| 1483 * |
| 1484 * @param width The grouping size to use. |
| 1485 * @see #setSecondaryGroupingSize |
| 1486 * @category Separators |
| 1487 * @stable ICU 2.0 |
| 1488 */ |
| 1489 public synchronized void setGroupingSize(int width) { |
| 1490 properties.setGroupingSize(width); |
| 1491 refreshFormatter(); |
| 1492 } |
| 1493 |
| 1494 /** |
| 1495 * @return The secondary grouping size in use. |
| 1496 * @see #setSecondaryGroupingSize |
| 1497 * @category Separators |
| 1498 * @stable ICU 2.0 |
| 1499 */ |
| 1500 public synchronized int getSecondaryGroupingSize() { |
| 1501 return exportedProperties.getSecondaryGroupingSize(); |
| 1502 } |
| 1503 |
| 1504 /** |
| 1505 * <strong>Grouping:</strong> Sets the secondary grouping size (distance betwe
en grouping |
| 1506 * separators after the first separator) used when formatting large numbers. I
n many south Asian |
| 1507 * locales, this is set to 2. |
| 1508 * |
| 1509 * <p>For example, with primary grouping size 3 and secondary grouping size 2,
the number 1234567 |
| 1510 * will be formatted as "12,34,567". |
| 1511 * |
| 1512 * <p>Grouping size can also be specified in the pattern: for example, "#,##,#
#0" corresponds to a |
| 1513 * primary grouping size of 3 and a secondary grouping size of 2. |
| 1514 * |
| 1515 * @param width The secondary grouping size to use. |
| 1516 * @see #setGroupingSize |
| 1517 * @category Separators |
| 1518 * @stable ICU 2.0 |
| 1519 */ |
| 1520 public synchronized void setSecondaryGroupingSize(int width) { |
| 1521 properties.setSecondaryGroupingSize(width); |
| 1522 refreshFormatter(); |
| 1523 } |
| 1524 |
| 1525 /** |
| 1526 * @return The minimum number of digits before grouping is triggered. |
| 1527 * @see #setMinimumGroupingDigits |
| 1528 * @category Separators |
| 1529 * @internal |
| 1530 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1531 */ |
| 1532 @Deprecated |
| 1533 public synchronized int getMinimumGroupingDigits() { |
| 1534 return properties.getMinimumGroupingDigits(); |
| 1535 } |
| 1536 |
| 1537 /** |
| 1538 * Sets the minimum number of digits that must be before the first grouping se
parator in order for |
| 1539 * the grouping separator to be printed. For example, if minimum grouping digi
ts is set to 2, in |
| 1540 * <em>en-US</em>, 1234 will be printed as "1234" and 12345 will be printed as
"12,345". |
| 1541 * |
| 1542 * @param number The minimum number of digits before grouping is triggered. |
| 1543 * @category Separators |
| 1544 * @internal |
| 1545 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1546 */ |
| 1547 @Deprecated |
| 1548 public synchronized void setMinimumGroupingDigits(int number) { |
| 1549 properties.setMinimumGroupingDigits(number); |
| 1550 refreshFormatter(); |
| 1551 } |
| 1552 |
| 1553 /** |
| 1554 * @return Whether the decimal separator is shown on integers. |
| 1555 * @see #setDecimalSeparatorAlwaysShown |
| 1556 * @category Separators |
| 1557 * @stable ICU 2.0 |
| 1558 */ |
| 1559 public synchronized boolean isDecimalSeparatorAlwaysShown() { |
| 1560 return exportedProperties.getDecimalSeparatorAlwaysShown(); |
| 1561 } |
| 1562 |
| 1563 /** |
| 1564 * <strong>Separators:</strong> Sets whether the decimal separator (a period i
n <em>en-US</em>) is |
| 1565 * shown on integers. For example, if this setting is turned on, formatting 12
3 will result in |
| 1566 * "123." with the decimal separator. |
| 1567 * |
| 1568 * <p>This setting can be specified in the pattern for integer formats: "#,##0
." is an example. |
| 1569 * |
| 1570 * @param value true to always show the decimal separator; false to show it on
ly when there is a |
| 1571 * fraction part of the number. |
| 1572 * @category Separators |
| 1573 * @stable ICU 2.0 |
| 1574 */ |
| 1575 public synchronized void setDecimalSeparatorAlwaysShown(boolean value) { |
| 1576 properties.setDecimalSeparatorAlwaysShown(value); |
| 1577 refreshFormatter(); |
| 1578 } |
| 1579 |
| 1580 /** |
| 1581 * @return The user-specified currency. May be null. |
| 1582 * @see #setCurrency |
| 1583 * @see DecimalFormatSymbols#getCurrency |
| 1584 * @category Currency |
| 1585 * @stable ICU 2.6 |
| 1586 */ |
749 @Override | 1587 @Override |
750 public synchronized Currency getCurrency() { | 1588 public synchronized Currency getCurrency() { |
751 return properties.getCurrency(); | 1589 return properties.getCurrency(); |
752 } | 1590 } |
753 | 1591 |
754 /** @stable ICU 2.2 */ | 1592 /** |
755 @Override | 1593 * Sets the currency to be used when formatting numbers. The effect is twofold
: |
756 public synchronized void setCurrency(Currency theCurrency) { | 1594 * |
757 properties.setCurrency(theCurrency); | 1595 * <ol> |
| 1596 * <li>Substitutions for currency symbols in the pattern string will use thi
s currency |
| 1597 * <li>The rounding mode will obey the rules for this currency (see {@link #
setCurrencyUsage}) |
| 1598 * </ol> |
| 1599 * |
| 1600 * <strong>Important:</strong> Displaying the currency in the output requires
that the patter |
| 1601 * associated with this formatter contains a currency symbol '¤'. This will be
the case if the |
| 1602 * instance was created via {@link #getCurrencyInstance} or one of its friends
. |
| 1603 * |
| 1604 * @param currency The currency to use. |
| 1605 * @category Currency |
| 1606 * @stable ICU 2.2 |
| 1607 */ |
| 1608 @Override |
| 1609 public synchronized void setCurrency(Currency currency) { |
| 1610 properties.setCurrency(currency); |
758 // Backwards compatibility: also set the currency in the DecimalFormatSymbol
s | 1611 // Backwards compatibility: also set the currency in the DecimalFormatSymbol
s |
759 if (theCurrency != null) { | 1612 if (currency != null) { |
760 symbols.setCurrency(theCurrency); | 1613 symbols.setCurrency(currency); |
761 String symbol = theCurrency.getName(symbols.getULocale(), Currency.SYMBOL_
NAME, null); | 1614 String symbol = currency.getName(symbols.getULocale(), Currency.SYMBOL_NAM
E, null); |
762 symbols.setCurrencySymbol(symbol); | 1615 symbols.setCurrencySymbol(symbol); |
763 } | 1616 } |
764 refreshFormatter(); | 1617 refreshFormatter(); |
765 } | 1618 } |
766 | 1619 |
767 /** @stable ICU 54 */ | 1620 /** |
768 public synchronized void setCurrencyUsage(CurrencyUsage newUsage) { | 1621 * @return The strategy for rounding currency amounts. |
769 properties.setCurrencyUsage(newUsage); | 1622 * @see #setCurrencyUsage |
770 refreshFormatter(); | 1623 * @category Currency |
771 } | 1624 * @stable ICU 54 |
772 | 1625 */ |
773 /** @stable ICU 54 */ | |
774 public synchronized CurrencyUsage getCurrencyUsage() { | 1626 public synchronized CurrencyUsage getCurrencyUsage() { |
775 // CurrencyUsage is not exported, so we have to get it from the input proper
ty bag. | 1627 // CurrencyUsage is not exported, so we have to get it from the input proper
ty bag. |
776 // TODO: Should we export CurrencyUsage instead? | 1628 // TODO: Should we export CurrencyUsage instead? |
777 CurrencyUsage usage = properties.getCurrencyUsage(); | 1629 CurrencyUsage usage = properties.getCurrencyUsage(); |
778 if (usage == null) { | 1630 if (usage == null) { |
779 usage = CurrencyUsage.STANDARD; | 1631 usage = CurrencyUsage.STANDARD; |
780 } | 1632 } |
781 return usage; | 1633 return usage; |
782 } | 1634 } |
783 | 1635 |
784 /** @stable ICU 4.2 */ | 1636 /** |
| 1637 * Sets the currency-dependent strategy to use when rounding numbers. There ar
e two strategies: |
| 1638 * |
| 1639 * <ul> |
| 1640 * <li>STANDARD: When the amount displayed is intended for banking statement
s or electronic |
| 1641 * transfer. |
| 1642 * <li>CASH: When the amount displayed is intended to be representable in ph
ysical currency, |
| 1643 * like at a cash register. |
| 1644 * </ul> |
| 1645 * |
| 1646 * CASH mode is relevant in currencies that do not have tender down to the pen
ny. For more |
| 1647 * information on the two rounding strategies, see <a |
| 1648 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Supplemental_Curren
cy_Data">UTS |
| 1649 * #35</a>. If omitted, the strategy defaults to STANDARD. To override currenc
y rounding |
| 1650 * altogether, use {@link #setMinimumFractionDigits} and {@link #setMaximumFra
ctionDigits} or |
| 1651 * {@link #setRoundingIncrement}. |
| 1652 * |
| 1653 * @param usage The strategy to use when rounding in the current currency. |
| 1654 * @category Currency |
| 1655 * @stable ICU 54 |
| 1656 */ |
| 1657 public synchronized void setCurrencyUsage(CurrencyUsage usage) { |
| 1658 properties.setCurrencyUsage(usage); |
| 1659 refreshFormatter(); |
| 1660 } |
| 1661 |
| 1662 /** |
| 1663 * @return The current instance of CurrencyPluralInfo. |
| 1664 * @see #setCurrencyPluralInfo |
| 1665 * @category Currency |
| 1666 * @stable ICU 4.2 |
| 1667 */ |
785 public CurrencyPluralInfo getCurrencyPluralInfo() { | 1668 public CurrencyPluralInfo getCurrencyPluralInfo() { |
786 // CurrencyPluralInfo also is not exported. | 1669 // CurrencyPluralInfo also is not exported. |
787 return properties.getCurrencyPluralInfo(); | 1670 return properties.getCurrencyPluralInfo(); |
788 } | 1671 } |
789 | 1672 |
790 /** @stable ICU 4.2 */ | 1673 /** |
| 1674 * Sets a custom instance of CurrencyPluralInfo. CurrencyPluralInfo generates
pattern strings for |
| 1675 * printing currency long names. |
| 1676 * |
| 1677 * <p><strong>Most users should not call this method directly.</strong> You sh
ould instead create |
| 1678 * your formatter via <code>NumberFormat.getInstance(NumberFormat.PLURALCURREN
CYSTYLE)</code>. |
| 1679 * |
| 1680 * @param newInfo The CurrencyPluralInfo to use when printing currency long na
mes. |
| 1681 * @category Currency |
| 1682 * @stable ICU 4.2 |
| 1683 */ |
791 public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { | 1684 public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) { |
792 properties.setCurrencyPluralInfo(newInfo); | 1685 properties.setCurrencyPluralInfo(newInfo); |
793 refreshFormatter(); | 1686 refreshFormatter(); |
794 } | 1687 } |
795 | 1688 |
796 /** @stable ICU 3.6 */ | 1689 /** |
| 1690 * @return Whether {@link #parse} will always return a BigDecimal |
| 1691 * @see #setParseBigDecimal |
| 1692 * @category Parsing |
| 1693 * @stable ICU 3.6 |
| 1694 */ |
| 1695 public synchronized boolean isParseBigDecimal() { |
| 1696 return properties.getParseToBigDecimal(); |
| 1697 } |
| 1698 |
| 1699 /** |
| 1700 * Whether to force {@link #parse} to always return a BigDecimal. By default,
{@link #parse} will |
| 1701 * return different data types as follows: |
| 1702 * |
| 1703 * <ol> |
| 1704 * <li>If the number is an integer (has no fraction part), return a Long if
possible, or else a |
| 1705 * BigInteger. |
| 1706 * <li>Otherwise, return a BigDecimal. |
| 1707 * </ol> |
| 1708 * |
| 1709 * If this setting is enabled, a BigDecimal will be returned even if the numbe
r is an integer. |
| 1710 * |
| 1711 * @param value true to cause {@link #parse} to always return a BigDecimal; fa
lse to let {@link |
| 1712 * #parse} return different data types. |
| 1713 * @category Parsing |
| 1714 * @stable ICU 3.6 |
| 1715 */ |
797 public synchronized void setParseBigDecimal(boolean value) { | 1716 public synchronized void setParseBigDecimal(boolean value) { |
798 properties.setParseToBigDecimal(value); | 1717 properties.setParseToBigDecimal(value); |
799 // refreshFormatter() not needed | 1718 // refreshFormatter() not needed |
800 } | 1719 } |
801 | 1720 |
802 /** @stable ICU 3.6 */ | 1721 /** |
803 public synchronized boolean isParseBigDecimal() { | 1722 * @return Always 1000, the default prior to ICU 59. |
804 return properties.getParseToBigDecimal(); | 1723 * @category Parsing |
805 } | 1724 * @deprecated Setting max parse digits has no effect since ICU4J 59. |
806 | 1725 */ |
807 /** | 1726 @Deprecated |
808 * Setting max parse digits has no effect since ICU 59. | 1727 public int getParseMaxDigits() { |
809 * | |
810 * @stable ICU 51 | |
811 */ | |
812 public synchronized void setParseMaxDigits(int _) { | |
813 } | |
814 | |
815 /** | |
816 * Setting max parse digits has no effect since ICU 59. | |
817 * Always returns 1000. | |
818 * | |
819 * @stable ICU 51 | |
820 */ | |
821 public synchronized int getParseMaxDigits() { | |
822 return 1000; | 1728 return 1000; |
823 } | 1729 } |
824 | 1730 |
| 1731 /** |
| 1732 * @param maxDigits Prior to ICU 59, the maximum number of digits in the outpu
t number after |
| 1733 * exponential notation is applied. |
| 1734 * @category Parsing |
| 1735 * @deprecated Setting max parse digits has no effect since ICU4J 59. |
| 1736 */ |
| 1737 @Deprecated |
| 1738 public void setParseMaxDigits(int maxDigits) {} |
| 1739 |
| 1740 /** |
| 1741 * {@inheritDoc} |
| 1742 * |
| 1743 * @category Parsing |
| 1744 * @stable ICU 3.6 |
| 1745 */ |
| 1746 @Override |
| 1747 public synchronized boolean isParseStrict() { |
| 1748 return properties.getParseMode() == Parse.ParseMode.STRICT; |
| 1749 } |
| 1750 |
| 1751 /** |
| 1752 * {@inheritDoc} |
| 1753 * |
| 1754 * @category Parsing |
| 1755 * @stable ICU 3.6 |
| 1756 */ |
825 @Override | 1757 @Override |
826 public synchronized void setParseStrict(boolean parseStrict) { | 1758 public synchronized void setParseStrict(boolean parseStrict) { |
827 Parse.ParseMode mode = parseStrict ? Parse.ParseMode.STRICT : Parse.ParseMod
e.LENIENT; | 1759 Parse.ParseMode mode = parseStrict ? Parse.ParseMode.STRICT : Parse.ParseMod
e.LENIENT; |
828 properties.setParseMode(mode); | 1760 properties.setParseMode(mode); |
829 // refreshFormatter() not needed | 1761 // refreshFormatter() not needed |
830 } | 1762 } |
831 | 1763 |
832 @Override | 1764 /** |
833 public synchronized boolean isParseStrict() { | 1765 * @return Whether parsing should stop before encountering a decimal point and
fraction part. |
834 return properties.getParseMode() == Parse.ParseMode.STRICT; | 1766 * @see #setParseIntegerOnly |
835 } | 1767 * @category Parsing |
836 | 1768 * @stable ICU 2.0 |
| 1769 */ |
| 1770 @Override |
| 1771 public synchronized boolean isParseIntegerOnly() { |
| 1772 return properties.getParseIntegerOnly(); |
| 1773 } |
| 1774 |
| 1775 /** |
| 1776 * <strong>Parsing:</strong> Whether to ignore the fraction part of a number w
hen parsing |
| 1777 * (defaults to false). If a string contains a decimal point, parsing will sto
p before the decimal |
| 1778 * point. Note that determining whether a character is a decimal point depends
on the locale. |
| 1779 * |
| 1780 * <p>For example, in <em>en-US</em>, parsing the string "123.45" will return
the number 123 and |
| 1781 * parse position 3. |
| 1782 * |
| 1783 * <p>This is functionally equivalent to calling {@link #setDecimalPatternMatc
hRequired} and a |
| 1784 * pattern without a decimal point. |
| 1785 * |
| 1786 * @param parseIntegerOnly true to ignore fractional parts of numbers when par
sing; false to |
| 1787 * consume fractional parts. |
| 1788 * @category Parsing |
| 1789 * @stable ICU 2.0 |
| 1790 */ |
837 @Override | 1791 @Override |
838 public synchronized void setParseIntegerOnly(boolean parseIntegerOnly) { | 1792 public synchronized void setParseIntegerOnly(boolean parseIntegerOnly) { |
839 properties.setParseIntegerOnly(parseIntegerOnly); | 1793 properties.setParseIntegerOnly(parseIntegerOnly); |
840 // refreshFormatter() not needed | 1794 // refreshFormatter() not needed |
841 } | 1795 } |
842 | 1796 |
843 @Override | 1797 /** |
844 public synchronized boolean isParseIntegerOnly() { | 1798 * @return Whether the presence of a decimal point must match the pattern. |
845 return properties.getParseIntegerOnly(); | 1799 * @see #setDecimalPatternMatchRequired |
846 } | 1800 * @category Parsing |
847 | 1801 * @stable ICU 54 |
848 /** @stable ICU 2.0 */ | 1802 */ |
| 1803 public synchronized boolean isDecimalPatternMatchRequired() { |
| 1804 return properties.getDecimalPatternMatchRequired(); |
| 1805 } |
| 1806 |
| 1807 /** |
| 1808 * <strong>Parsing:</strong> This method is used to either <em>require</em> or
<em>forbid</em> the |
| 1809 * presence of a decimal point in the string being parsed (disabled by default
). This feature was |
| 1810 * designed to be an extra layer of strictness on top of strict parsing, altho
ugh it can be used |
| 1811 * in either lenient mode or strict mode. |
| 1812 * |
| 1813 * <p>To <em>require</em> a decimal point, call this method in combination wit
h either a pattern |
| 1814 * containing a decimal point or with {@link #setDecimalSeparatorAlwaysShown}. |
| 1815 * |
| 1816 * <pre> |
| 1817 * // Require a decimal point in the string being parsed: |
| 1818 * df.applyPattern("#."); |
| 1819 * df.setDecimalPatternMatchRequired(true); |
| 1820 * |
| 1821 * // Alternatively: |
| 1822 * df.setDecimalSeparatorAlwaysShown(true); |
| 1823 * df.setDecimalPatternMatchRequired(true); |
| 1824 * </pre> |
| 1825 * |
| 1826 * To <em>forbid</em> a decimal point, call this method in combination with a
pattern containing |
| 1827 * no decimal point. Alternatively, use {@link #setParseIntegerOnly} for the s
ame behavior without |
| 1828 * depending on the contents of the pattern string. |
| 1829 * |
| 1830 * <pre> |
| 1831 * // Forbid a decimal point in the string being parsed: |
| 1832 * df.applyPattern("#"); |
| 1833 * df.setDecimalPatternMatchRequired(true); |
| 1834 * </pre> |
| 1835 * |
| 1836 * @param value true to either require or forbid the decimal point according t
o the pattern; false |
| 1837 * to disable this feature. |
| 1838 * @see #setParseIntegerOnly |
| 1839 * @category Parsing |
| 1840 * @stable ICU 54 |
| 1841 */ |
| 1842 public synchronized void setDecimalPatternMatchRequired(boolean value) { |
| 1843 properties.setDecimalPatternMatchRequired(value); |
| 1844 refreshFormatter(); |
| 1845 } |
| 1846 |
| 1847 /** |
| 1848 * @return Whether to ignore exponents when parsing. |
| 1849 * @see #setParseNoExponent |
| 1850 * @category Parsing |
| 1851 * @internal |
| 1852 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1853 */ |
| 1854 @Deprecated |
| 1855 public synchronized boolean getParseNoExponent() { |
| 1856 return properties.getParseNoExponent(); |
| 1857 } |
| 1858 |
| 1859 /** |
| 1860 * Specifies whether to stop parsing when an exponent separator is encountered
. For example, |
| 1861 * parses "123E4" to 123 (with parse position 3) instead of 1230000 (with pars
e position 5). |
| 1862 * |
| 1863 * @param value true to prevent exponents from being parsed; false to allow th
em to be parsed. |
| 1864 * @category Parsing |
| 1865 * @internal |
| 1866 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1867 */ |
| 1868 @Deprecated |
| 1869 public synchronized void setParseNoExponent(boolean value) { |
| 1870 properties.setParseNoExponent(value); |
| 1871 refreshFormatter(); |
| 1872 } |
| 1873 |
| 1874 /** |
| 1875 * @return Whether to force case (uppercase/lowercase) to match when parsing. |
| 1876 * @see #setParseNoExponent |
| 1877 * @category Parsing |
| 1878 * @internal |
| 1879 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1880 */ |
| 1881 @Deprecated |
| 1882 public synchronized boolean getParseCaseSensitive() { |
| 1883 return properties.getParseCaseSensitive(); |
| 1884 } |
| 1885 |
| 1886 /** |
| 1887 * Specifies whether parsing should require cases to match in affixes, exponen
t separators, and |
| 1888 * currency codes. Case mapping is performed for each code point using {@link |
| 1889 * UCharacter#foldCase}. |
| 1890 * |
| 1891 * @param value true to force case (uppercase/lowercase) to match when parsing
; false to ignore |
| 1892 * case and perform case folding. |
| 1893 * @category Parsing |
| 1894 * @internal |
| 1895 * @deprecated ICU 59: This API is a technical preview. It may change in an up
coming release. |
| 1896 */ |
| 1897 @Deprecated |
| 1898 public synchronized void setParseCaseSensitive(boolean value) { |
| 1899 properties.setParseCaseSensitive(value); |
| 1900 refreshFormatter(); |
| 1901 } |
| 1902 |
| 1903 //============================================================================
=========// |
| 1904 // UTILITIES
// |
| 1905 //============================================================================
=========// |
| 1906 |
| 1907 /** |
| 1908 * Tests for equality between this formatter and another formatter. |
| 1909 * |
| 1910 * <p>If two DecimalFormat instances are equal, then they will always produce
the same output. |
| 1911 * However, the reverse is not necessarily true: if two DecimalFormat instance
s always produce the |
| 1912 * same output, they are not necessarily equal. |
| 1913 * |
| 1914 * @stable ICU 2.0 |
| 1915 */ |
849 @Override | 1916 @Override |
850 public synchronized boolean equals(Object obj) { | 1917 public synchronized boolean equals(Object obj) { |
851 if (obj == null) return false; | 1918 if (obj == null) return false; |
852 if (obj == this) return true; | 1919 if (obj == this) return true; |
853 if (!(obj instanceof DecimalFormat)) return false; | 1920 if (!(obj instanceof DecimalFormat)) return false; |
854 DecimalFormat other = (DecimalFormat) obj; | 1921 DecimalFormat other = (DecimalFormat) obj; |
855 return properties.equals(other.properties) && symbols.equals(other.symbols); | 1922 return properties.equals(other.properties) && symbols.equals(other.symbols); |
856 } | 1923 } |
857 | 1924 |
858 /** @stable ICU 2.0 */ | 1925 /** @stable ICU 2.0 */ |
859 @Override | 1926 @Override |
860 public synchronized int hashCode() { | 1927 public synchronized int hashCode() { |
861 return properties.hashCode(); | 1928 return properties.hashCode(); |
862 } | 1929 } |
863 | 1930 |
864 private static final ThreadLocal<Properties> threadLocalToPatternProperties = | 1931 private static final ThreadLocal<Properties> threadLocalToPatternProperties = |
865 new ThreadLocal<Properties>() { | 1932 new ThreadLocal<Properties>() { |
866 @Override | 1933 @Override |
867 protected Properties initialValue() { | 1934 protected Properties initialValue() { |
868 return new Properties(); | 1935 return new Properties(); |
869 } | 1936 } |
870 }; | 1937 }; |
871 | 1938 |
872 /** @stable ICU 2.0 */ | 1939 @Override |
| 1940 public synchronized String toString() { |
| 1941 return "<DecimalFormat " + symbols.toString() + " " + properties.toString()
+ ">"; |
| 1942 } |
| 1943 |
| 1944 /** |
| 1945 * Serializes this formatter object to a decimal format pattern string. The re
sult of this method |
| 1946 * is guaranteed to be <em>functionally</em> equivalent to the pattern string
used to create this |
| 1947 * instance after incorporating values from the setter methods. |
| 1948 * |
| 1949 * <p>For more information on decimal format pattern strings, see <a |
| 1950 * href="http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patte
rns">UTS #35</a>. |
| 1951 * |
| 1952 * <p><strong>Important:</strong> Not all properties are capable of being enco
ded in a pattern |
| 1953 * string. See a list of properties in {@link #applyPattern}. |
| 1954 * |
| 1955 * @return A decimal format pattern string. |
| 1956 * @stable ICU 2.0 |
| 1957 */ |
873 public synchronized String toPattern() { | 1958 public synchronized String toPattern() { |
874 // Pull some properties from exportedProperties and others from properties | 1959 // Pull some properties from exportedProperties and others from properties |
875 // to keep affix patterns intact. In particular, pull rounding properties | 1960 // to keep affix patterns intact. In particular, pull rounding properties |
876 // so that CurrencyUsage is reflected properly. | 1961 // so that CurrencyUsage is reflected properly. |
877 // TODO: Consider putting this logic in PatternString.java instead. | 1962 // TODO: Consider putting this logic in PatternString.java instead. |
878 Properties tprops = threadLocalToPatternProperties.get(); | 1963 Properties tprops = threadLocalToPatternProperties.get(); |
879 tprops.copyFrom(properties); | 1964 tprops.copyFrom(properties); |
880 if (com.ibm.icu.impl.number.formatters.CurrencyFormat.useCurrency(properties
)) { | 1965 if (com.ibm.icu.impl.number.formatters.CurrencyFormat.useCurrency(properties
)) { |
881 tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigit
s()); | 1966 tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigit
s()); |
882 tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigit
s()); | 1967 tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigit
s()); |
883 tprops.setRoundingInterval(exportedProperties.getRoundingInterval()); | 1968 tprops.setRoundingIncrement(exportedProperties.getRoundingIncrement()); |
884 } | 1969 } |
885 return PatternString.propertiesToString(tprops); | 1970 return PatternString.propertiesToString(tprops); |
886 } | 1971 } |
887 | 1972 |
888 /** @stable ICU 2.0 */ | 1973 /** |
| 1974 * Calls {@link #toPattern} and converts the string to localized notation. For
more information on |
| 1975 * localized notation, see {@link #applyLocalizedPattern}. |
| 1976 * |
| 1977 * @return A decimal format pattern string in localized notation. |
| 1978 * @stable ICU 2.0 |
| 1979 */ |
889 public synchronized String toLocalizedPattern() { | 1980 public synchronized String toLocalizedPattern() { |
890 String pattern = toPattern(); | 1981 String pattern = toPattern(); |
891 return PatternString.convertLocalized(pattern, symbols, true); | 1982 return PatternString.convertLocalized(pattern, symbols, true); |
892 } | 1983 } |
893 | 1984 |
894 /** | 1985 /** |
895 * @internal | 1986 * @internal |
896 * @deprecated This API is ICU internal only. | 1987 * @deprecated This API is ICU internal only. |
897 */ | 1988 */ |
898 @Deprecated | 1989 @Deprecated |
899 public IFixedDecimal getFixedDecimal(double number) { | 1990 public IFixedDecimal getFixedDecimal(double number) { |
900 FormatQuantity4 fq = new FormatQuantity4(number); | 1991 FormatQuantity4 fq = new FormatQuantity4(number); |
901 formatter.format(fq); | 1992 formatter.format(fq); |
902 return fq; | 1993 return fq; |
903 } | 1994 } |
904 | 1995 |
905 /** | 1996 /** Rebuilds the formatter object from the property bag. */ |
906 * Rebuilds the formatter object from the property bag. | |
907 */ | |
908 void refreshFormatter() { | 1997 void refreshFormatter() { |
| 1998 if (exportedProperties == null) { |
| 1999 // exportedProperties is null only when the formatter is not ready yet. |
| 2000 // The only time when this happens is during legacy deserialization. |
| 2001 return; |
| 2002 } |
909 formatter = Endpoint.fromBTA(properties, symbols); | 2003 formatter = Endpoint.fromBTA(properties, symbols); |
910 exportedProperties.clear(); | 2004 exportedProperties.clear(); |
911 formatter.export(exportedProperties); | 2005 formatter.export(exportedProperties); |
912 } | 2006 } |
913 | 2007 |
914 /** | 2008 /** |
915 * Updates the property bag with settings from the given pattern. | 2009 * Updates the property bag with settings from the given pattern. |
| 2010 * |
916 * @param pattern The pattern string to parse. | 2011 * @param pattern The pattern string to parse. |
917 * @param ignoreRounding Whether to read rounding information from the string.
Set to false if | 2012 * @param ignoreRounding Whether to read rounding information from the string.
Set to false if |
918 * CurrencyUsage is to be used instead. | 2013 * CurrencyUsage is to be used instead. |
919 * @see PatternString#parseToExistingProperties | 2014 * @see PatternString#parseToExistingProperties |
920 */ | 2015 */ |
921 void setPropertiesFromPattern(String pattern, boolean ignoreRounding) { | 2016 void setPropertiesFromPattern(String pattern, boolean ignoreRounding) { |
922 PatternString.parseToExistingProperties(pattern, properties, ignoreRounding)
; | 2017 PatternString.parseToExistingProperties(pattern, properties, ignoreRounding)
; |
923 } | 2018 } |
924 | 2019 |
925 /** | 2020 /** |
926 * @internal | 2021 * @internal |
927 * @deprecated This API is a technical preview. | 2022 * @deprecated This API is ICU internal only. |
928 */ | 2023 */ |
929 @Deprecated | 2024 @Deprecated |
930 public synchronized void setProperties(PropertySetter func) { | 2025 public synchronized void setProperties(PropertySetter func) { |
931 func.set(properties); | 2026 func.set(properties); |
932 refreshFormatter(); | 2027 refreshFormatter(); |
933 } | 2028 } |
934 | 2029 |
935 public static interface PropertySetter { | 2030 public static interface PropertySetter { |
936 public void set(Properties props); | 2031 public void set(Properties props); |
937 } | 2032 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 * | 2076 * |
982 * @see #setPadPosition | 2077 * @see #setPadPosition |
983 * @see #getPadPosition | 2078 * @see #getPadPosition |
984 * @see #PAD_BEFORE_PREFIX | 2079 * @see #PAD_BEFORE_PREFIX |
985 * @see #PAD_AFTER_PREFIX | 2080 * @see #PAD_AFTER_PREFIX |
986 * @see #PAD_BEFORE_SUFFIX | 2081 * @see #PAD_BEFORE_SUFFIX |
987 * @stable ICU 2.0 | 2082 * @stable ICU 2.0 |
988 */ | 2083 */ |
989 public static final int PAD_AFTER_SUFFIX = 3; | 2084 public static final int PAD_AFTER_SUFFIX = 3; |
990 } | 2085 } |
LEFT | RIGHT |