8177552: Compact Number Formatting support
Reviewed-by: naoto, rriggs
This commit is contained in:
parent
f3646ad79b
commit
4a28e27fd2
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -151,6 +151,19 @@ abstract class AbstractLDMLHandler<V> extends DefaultHandler {
|
||||
}
|
||||
}
|
||||
|
||||
void pushStringListEntry(String qName, Attributes attributes, String key) {
|
||||
if (!pushIfIgnored(qName, attributes)) {
|
||||
currentContainer = new StringListEntry(qName, currentContainer, key);
|
||||
}
|
||||
}
|
||||
|
||||
void pushStringListElement(String qName, Attributes attributes, int index) {
|
||||
if (!pushIfIgnored(qName, attributes)) {
|
||||
currentContainer = new StringListElement(qName, currentContainer, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean pushIfIgnored(String qName, Attributes attributes) {
|
||||
if (isIgnored(attributes) || currentContainer instanceof IgnoredContainer) {
|
||||
pushIgnoredContainer(qName);
|
||||
|
@ -53,6 +53,10 @@ class Bundle {
|
||||
"NumberPatterns/percent"
|
||||
};
|
||||
|
||||
private final static String[] COMPACT_NUMBER_PATTERN_KEYS = {
|
||||
"short.CompactNumberPatterns",
|
||||
"long.CompactNumberPatterns"};
|
||||
|
||||
private final static String[] NUMBER_ELEMENT_KEYS = {
|
||||
"NumberElements/decimal",
|
||||
"NumberElements/group",
|
||||
@ -228,6 +232,16 @@ class Bundle {
|
||||
}
|
||||
}
|
||||
|
||||
for (String k : COMPACT_NUMBER_PATTERN_KEYS) {
|
||||
List<String> patterns = (List<String>) myMap.remove(k);
|
||||
if (patterns != null) {
|
||||
// Replace any null entry with empty strings.
|
||||
String[] arrPatterns = patterns.stream()
|
||||
.map(s -> s == null ? "" : s).toArray(String[]::new);
|
||||
myMap.put(k, arrPatterns);
|
||||
}
|
||||
}
|
||||
|
||||
// if myMap has any of NUMBER_ELEMENT_KEYS, create a complete NumberElements.
|
||||
String defaultScript = (String) myMap.get("DefaultNumberingSystem");
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -888,6 +888,8 @@ public class CLDRConverter {
|
||||
copyIfPresent(map, "NumberElements", formatData);
|
||||
}
|
||||
copyIfPresent(map, "NumberPatterns", formatData);
|
||||
copyIfPresent(map, "short.CompactNumberPatterns", formatData);
|
||||
copyIfPresent(map, "long.CompactNumberPatterns", formatData);
|
||||
|
||||
// put extra number elements for available scripts into formatData, if it is "root"
|
||||
if (id.equals("root")) {
|
||||
|
@ -52,6 +52,8 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
private final String id;
|
||||
private String currentContext = ""; // "format"/"stand-alone"
|
||||
private String currentWidth = ""; // "wide"/"narrow"/"abbreviated"
|
||||
private String currentStyle = ""; // short, long for decimalFormat
|
||||
private String compactCount = ""; // one or other for decimalFormat
|
||||
|
||||
LDMLParseHandler(String id) {
|
||||
this.id = id;
|
||||
@ -503,13 +505,85 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// Number format information
|
||||
//
|
||||
case "decimalFormatLength":
|
||||
if (attributes.getValue("type") == null) {
|
||||
// skipping type="short" data
|
||||
// for FormatData
|
||||
// copy string for later assembly into NumberPatterns
|
||||
String type = attributes.getValue("type");
|
||||
if (null == type) {
|
||||
// format data for decimal number format
|
||||
pushStringEntry(qName, attributes, "NumberPatterns/decimal");
|
||||
currentStyle = type;
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
switch (type) {
|
||||
case "short":
|
||||
case "long":
|
||||
// considering "short" and long for
|
||||
// compact number formatting patterns
|
||||
pushKeyContainer(qName, attributes, type);
|
||||
currentStyle = type;
|
||||
break;
|
||||
default:
|
||||
pushIgnoredContainer(qName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "decimalFormat":
|
||||
if(currentStyle == null) {
|
||||
pushContainer(qName, attributes);
|
||||
} else {
|
||||
switch (currentStyle) {
|
||||
case "short":
|
||||
pushStringListEntry(qName, attributes,
|
||||
currentStyle+".CompactNumberPatterns");
|
||||
break;
|
||||
case "long":
|
||||
pushStringListEntry(qName, attributes,
|
||||
currentStyle+".CompactNumberPatterns");
|
||||
break;
|
||||
default:
|
||||
pushIgnoredContainer(qName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "pattern":
|
||||
String containerName = currentContainer.getqName();
|
||||
if (containerName.equals("decimalFormat")) {
|
||||
if (currentStyle == null) {
|
||||
pushContainer(qName, attributes);
|
||||
} else {
|
||||
// The compact number patterns parsing assumes that the order
|
||||
// of patterns are always in the increasing order of their
|
||||
// type attribute i.e. type = 1000...
|
||||
// Between the inflectional forms for a type (e.g.
|
||||
// count = "one" and count = "other" for type = 1000), it is
|
||||
// assumed that the count = "one" always appears before
|
||||
// count = "other"
|
||||
switch (currentStyle) {
|
||||
case "short":
|
||||
case "long":
|
||||
String count = attributes.getValue("count");
|
||||
// first pattern of count = "one" or count = "other"
|
||||
if ((count.equals("one") || count.equals("other"))
|
||||
&& compactCount.equals("")) {
|
||||
compactCount = count;
|
||||
pushStringListElement(qName, attributes,
|
||||
(int) Math.log10(Double.parseDouble(attributes.getValue("type"))));
|
||||
} else if ((count.equals("one") || count.equals("other"))
|
||||
&& compactCount.equals(count)) {
|
||||
// extract patterns with similar "count"
|
||||
// attribute value
|
||||
pushStringListElement(qName, attributes,
|
||||
(int) Math.log10(Double.parseDouble(attributes.getValue("type"))));
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pushIgnoredContainer(qName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pushContainer(qName, attributes);
|
||||
}
|
||||
break;
|
||||
case "currencyFormatLength":
|
||||
@ -676,10 +750,9 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
// "alias" for root
|
||||
case "alias":
|
||||
{
|
||||
if (id.equals("root") &&
|
||||
!isIgnored(attributes) &&
|
||||
currentCalendarType != null &&
|
||||
!currentCalendarType.lname().startsWith("islamic-")) { // ignore Islamic variants
|
||||
if (id.equals("root") && !isIgnored(attributes)
|
||||
&& ((currentContainer.getqName().equals("decimalFormatLength"))
|
||||
|| (currentCalendarType != null && !currentCalendarType.lname().startsWith("islamic-")))) { // ignore islamic variants
|
||||
pushAliasEntry(qName, attributes, attributes.getValue("path"));
|
||||
} else {
|
||||
pushIgnoredContainer(qName);
|
||||
@ -831,6 +904,9 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
case "dayPeriods":
|
||||
case "eras":
|
||||
break;
|
||||
case "decimalFormatLength": // used for compact number formatting patterns
|
||||
keyName = type + ".CompactNumberPatterns";
|
||||
break;
|
||||
default:
|
||||
keyName = "";
|
||||
break;
|
||||
@ -869,6 +945,14 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
width = path.substring(start+typeKey.length(), path.indexOf("']", start));
|
||||
}
|
||||
|
||||
// used for compact number formatting patterns aliases
|
||||
typeKey = "decimalFormatLength[@type='";
|
||||
start = path.indexOf(typeKey);
|
||||
if (start != -1) {
|
||||
String style = path.substring(start + typeKey.length(), path.indexOf("']", start));
|
||||
return toJDKKey(qName, "", style);
|
||||
}
|
||||
|
||||
return calType + "." + toJDKKey(qName, context, width);
|
||||
}
|
||||
|
||||
@ -926,7 +1010,11 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
currentContext = "";
|
||||
putIfEntry();
|
||||
break;
|
||||
|
||||
case "decimalFormatLength":
|
||||
currentStyle = "";
|
||||
compactCount = "";
|
||||
putIfEntry();
|
||||
break;
|
||||
default:
|
||||
putIfEntry();
|
||||
}
|
||||
@ -937,22 +1025,28 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
||||
if (currentContainer instanceof AliasEntry) {
|
||||
Entry<?> entry = (Entry<?>) currentContainer;
|
||||
String containerqName = entry.getParent().getqName();
|
||||
Set<String> keyNames = populateAliasKeys(containerqName, currentContext, currentWidth);
|
||||
if (!keyNames.isEmpty()) {
|
||||
for (String keyName : keyNames) {
|
||||
String[] tmp = keyName.split(",", 3);
|
||||
String calType = currentCalendarType.lname();
|
||||
String src = calType+"."+tmp[0];
|
||||
String target = getTarget(
|
||||
entry.getKey(),
|
||||
calType,
|
||||
tmp[1].length()>0 ? tmp[1] : currentContext,
|
||||
tmp[2].length()>0 ? tmp[2] : currentWidth);
|
||||
if (target.substring(target.lastIndexOf('.')+1).equals(containerqName)) {
|
||||
target = target.substring(0, target.indexOf('.'))+"."+tmp[0];
|
||||
if (containerqName.equals("decimalFormatLength")) {
|
||||
String srcKey = toJDKKey(containerqName, "", currentStyle);
|
||||
String targetKey = getTarget(entry.getKey(), "", "", "");
|
||||
CLDRConverter.aliases.put(srcKey, targetKey);
|
||||
} else {
|
||||
Set<String> keyNames = populateAliasKeys(containerqName, currentContext, currentWidth);
|
||||
if (!keyNames.isEmpty()) {
|
||||
for (String keyName : keyNames) {
|
||||
String[] tmp = keyName.split(",", 3);
|
||||
String calType = currentCalendarType.lname();
|
||||
String src = calType+"."+tmp[0];
|
||||
String target = getTarget(
|
||||
entry.getKey(),
|
||||
calType,
|
||||
tmp[1].length()>0 ? tmp[1] : currentContext,
|
||||
tmp[2].length()>0 ? tmp[2] : currentWidth);
|
||||
if (target.substring(target.lastIndexOf('.')+1).equals(containerqName)) {
|
||||
target = target.substring(0, target.indexOf('.'))+"."+tmp[0];
|
||||
}
|
||||
CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""),
|
||||
target.replaceFirst("^gregorian.", ""));
|
||||
}
|
||||
CLDRConverter.aliases.put(src.replaceFirst("^gregorian.", ""),
|
||||
target.replaceFirst("^gregorian.", ""));
|
||||
}
|
||||
}
|
||||
} else if (currentContainer instanceof Entry) {
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package build.tools.cldrconverter;
|
||||
|
||||
class StringListElement extends Container {
|
||||
|
||||
StringListEntry list;
|
||||
int index;
|
||||
|
||||
StringListElement(String qName, Container parent, int index) {
|
||||
super(qName, parent);
|
||||
while (!(parent instanceof StringListEntry)) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
list = (StringListEntry) parent;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
void addCharacters(char[] characters, int start, int length) {
|
||||
list.addCharacters(index, characters, start, length);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package build.tools.cldrconverter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
class StringListEntry extends Entry<List<String>> {
|
||||
|
||||
private List<String> value;
|
||||
|
||||
StringListEntry(String qName, Container parent, String key) {
|
||||
super(qName, parent, key);
|
||||
value = new ArrayList<>();
|
||||
}
|
||||
|
||||
void addCharacters(int index, char[] characters, int start, int length) {
|
||||
// fill with empty strings when the patterns start from index > 0
|
||||
if (value.size() < index) {
|
||||
IntStream.range(0, index).forEach(i -> value.add(i, ""));
|
||||
value.add(index, new String(characters, start, length));
|
||||
} else {
|
||||
value.add(index, new String(characters, start, length));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
List<String> getValue() {
|
||||
for (String element : value) {
|
||||
if (element != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
2130
src/java.base/share/classes/java/text/CompactNumberFormat.java
Normal file
2130
src/java.base/share/classes/java/text/CompactNumberFormat.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -48,9 +48,6 @@ import java.text.spi.NumberFormatProvider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
@ -157,7 +154,7 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
|
||||
* used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
|
||||
* <code>"##,####,####"</code>.
|
||||
*
|
||||
* <h4>Special Pattern Characters</h4>
|
||||
* <h4><a id="special_pattern_character">Special Pattern Characters</a></h4>
|
||||
*
|
||||
* <p>Many characters in a pattern are taken literally; they are matched during
|
||||
* parsing and output unchanged during formatting. Special characters, on the
|
||||
@ -572,14 +569,11 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @return The formatted number string
|
||||
*/
|
||||
private StringBuffer format(double number, StringBuffer result,
|
||||
StringBuffer format(double number, StringBuffer result,
|
||||
FieldDelegate delegate) {
|
||||
if (Double.isNaN(number) ||
|
||||
(Double.isInfinite(number) && multiplier == 0)) {
|
||||
int iFieldStart = result.length();
|
||||
result.append(symbols.getNaN());
|
||||
delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
|
||||
iFieldStart, result.length(), result);
|
||||
|
||||
boolean nanOrInfinity = handleNaN(number, result, delegate);
|
||||
if (nanOrInfinity) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -599,6 +593,56 @@ public class DecimalFormat extends NumberFormat {
|
||||
number *= multiplier;
|
||||
}
|
||||
|
||||
nanOrInfinity = handleInfinity(number, result, delegate, isNegative);
|
||||
if (nanOrInfinity) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (isNegative) {
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// at this point we are guaranteed a nonnegative finite number.
|
||||
assert (number >= 0 && !Double.isInfinite(number));
|
||||
return doubleSubformat(number, result, delegate, isNegative);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given {@code number} is {@code Double.NaN}. if yes;
|
||||
* appends the NaN symbol to the result string. The NaN string is
|
||||
* determined by the DecimalFormatSymbols object.
|
||||
* @param number the double number to format
|
||||
* @param result where the text is to be appended
|
||||
* @param delegate notified of locations of sub fields
|
||||
* @return true, if number is a NaN; false otherwise
|
||||
*/
|
||||
boolean handleNaN(double number, StringBuffer result,
|
||||
FieldDelegate delegate) {
|
||||
if (Double.isNaN(number)
|
||||
|| (Double.isInfinite(number) && multiplier == 0)) {
|
||||
int iFieldStart = result.length();
|
||||
result.append(symbols.getNaN());
|
||||
delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
|
||||
iFieldStart, result.length(), result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given {@code number} is {@code Double.NEGATIVE_INFINITY}
|
||||
* or {@code Double.POSITIVE_INFINITY}. if yes;
|
||||
* appends the infinity string to the result string. The infinity string is
|
||||
* determined by the DecimalFormatSymbols object.
|
||||
* @param number the double number to format
|
||||
* @param result where the text is to be appended
|
||||
* @param delegate notified of locations of sub fields
|
||||
* @param isNegative whether the given {@code number} is negative
|
||||
* @return true, if number is a {@code Double.NEGATIVE_INFINITY} or
|
||||
* {@code Double.POSITIVE_INFINITY}; false otherwise
|
||||
*/
|
||||
boolean handleInfinity(double number, StringBuffer result,
|
||||
FieldDelegate delegate, boolean isNegative) {
|
||||
if (Double.isInfinite(number)) {
|
||||
if (isNegative) {
|
||||
append(result, negativePrefix, delegate,
|
||||
@ -621,27 +665,24 @@ public class DecimalFormat extends NumberFormat {
|
||||
getPositiveSuffixFieldPositions(), Field.SIGN);
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNegative) {
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// at this point we are guaranteed a nonnegative finite number.
|
||||
assert(number >= 0 && !Double.isInfinite(number));
|
||||
|
||||
synchronized(digitList) {
|
||||
StringBuffer doubleSubformat(double number, StringBuffer result,
|
||||
FieldDelegate delegate, boolean isNegative) {
|
||||
synchronized (digitList) {
|
||||
int maxIntDigits = super.getMaximumIntegerDigits();
|
||||
int minIntDigits = super.getMinimumIntegerDigits();
|
||||
int maxFraDigits = super.getMaximumFractionDigits();
|
||||
int minFraDigits = super.getMinimumFractionDigits();
|
||||
|
||||
digitList.set(isNegative, number, useExponentialNotation ?
|
||||
maxIntDigits + maxFraDigits : maxFraDigits,
|
||||
!useExponentialNotation);
|
||||
digitList.set(isNegative, number, useExponentialNotation
|
||||
? maxIntDigits + maxFraDigits : maxFraDigits,
|
||||
!useExponentialNotation);
|
||||
return subformat(result, delegate, isNegative, false,
|
||||
maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
|
||||
maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
|
||||
}
|
||||
}
|
||||
|
||||
@ -683,7 +724,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
private StringBuffer format(long number, StringBuffer result,
|
||||
StringBuffer format(long number, StringBuffer result,
|
||||
FieldDelegate delegate) {
|
||||
boolean isNegative = (number < 0);
|
||||
if (isNegative) {
|
||||
@ -774,7 +815,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @return The formatted number string
|
||||
*/
|
||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
FieldDelegate delegate) {
|
||||
if (multiplier != 1) {
|
||||
number = number.multiply(getBigDecimalMultiplier());
|
||||
@ -835,7 +876,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
||||
StringBuffer format(BigInteger number, StringBuffer result,
|
||||
FieldDelegate delegate, boolean formatLong) {
|
||||
if (multiplier != 1) {
|
||||
number = number.multiply(getBigIntegerMultiplier());
|
||||
@ -917,7 +958,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
return delegate.getIterator(sb.toString());
|
||||
}
|
||||
|
||||
// ==== Begin fast-path formating logic for double =========================
|
||||
// ==== Begin fast-path formatting logic for double =========================
|
||||
|
||||
/* Fast-path formatting will be used for format(double ...) methods iff a
|
||||
* number of conditions are met (see checkAndSetFastPathStatus()):
|
||||
@ -1662,6 +1703,26 @@ public class DecimalFormat extends NumberFormat {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code DigitList} used by this {@code DecimalFormat}
|
||||
* instance.
|
||||
* @param number the number to format
|
||||
* @param isNegative true, if the number is negative; false otherwise
|
||||
* @param maxDigits the max digits
|
||||
*/
|
||||
void setDigitList(Number number, boolean isNegative, int maxDigits) {
|
||||
|
||||
if (number instanceof Double) {
|
||||
digitList.set(isNegative, (Double) number, maxDigits, true);
|
||||
} else if (number instanceof BigDecimal) {
|
||||
digitList.set(isNegative, (BigDecimal) number, maxDigits, true);
|
||||
} else if (number instanceof Long) {
|
||||
digitList.set(isNegative, (Long) number, maxDigits);
|
||||
} else if (number instanceof BigInteger) {
|
||||
digitList.set(isNegative, (BigInteger) number, maxDigits);
|
||||
}
|
||||
}
|
||||
|
||||
// ======== End fast-path formating logic for double =========================
|
||||
|
||||
/**
|
||||
@ -1669,29 +1730,59 @@ public class DecimalFormat extends NumberFormat {
|
||||
* be filled in with the correct digits.
|
||||
*/
|
||||
private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
|
||||
boolean isNegative, boolean isInteger,
|
||||
int maxIntDigits, int minIntDigits,
|
||||
int maxFraDigits, int minFraDigits) {
|
||||
// NOTE: This isn't required anymore because DigitList takes care of this.
|
||||
//
|
||||
// // The negative of the exponent represents the number of leading
|
||||
// // zeros between the decimal and the first non-zero digit, for
|
||||
// // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
|
||||
// // is more than the maximum fraction digits, then we have an underflow
|
||||
// // for the printed representation. We recognize this here and set
|
||||
// // the DigitList representation to zero in this situation.
|
||||
//
|
||||
// if (-digitList.decimalAt >= getMaximumFractionDigits())
|
||||
// {
|
||||
// digitList.count = 0;
|
||||
// }
|
||||
boolean isNegative, boolean isInteger,
|
||||
int maxIntDigits, int minIntDigits,
|
||||
int maxFraDigits, int minFraDigits) {
|
||||
|
||||
// Process prefix
|
||||
if (isNegative) {
|
||||
append(result, negativePrefix, delegate,
|
||||
getNegativePrefixFieldPositions(), Field.SIGN);
|
||||
} else {
|
||||
append(result, positivePrefix, delegate,
|
||||
getPositivePrefixFieldPositions(), Field.SIGN);
|
||||
}
|
||||
|
||||
// Process number
|
||||
subformatNumber(result, delegate, isNegative, isInteger,
|
||||
maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
|
||||
|
||||
// Process suffix
|
||||
if (isNegative) {
|
||||
append(result, negativeSuffix, delegate,
|
||||
getNegativeSuffixFieldPositions(), Field.SIGN);
|
||||
} else {
|
||||
append(result, positiveSuffix, delegate,
|
||||
getPositiveSuffixFieldPositions(), Field.SIGN);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subformats number part using the {@code DigitList} of this
|
||||
* {@code DecimalFormat} instance.
|
||||
* @param result where the text is to be appended
|
||||
* @param delegate notified of the location of sub fields
|
||||
* @param isNegative true, if the number is negative; false otherwise
|
||||
* @param isInteger true, if the number is an integer; false otherwise
|
||||
* @param maxIntDigits maximum integer digits
|
||||
* @param minIntDigits minimum integer digits
|
||||
* @param maxFraDigits maximum fraction digits
|
||||
* @param minFraDigits minimum fraction digits
|
||||
*/
|
||||
void subformatNumber(StringBuffer result, FieldDelegate delegate,
|
||||
boolean isNegative, boolean isInteger,
|
||||
int maxIntDigits, int minIntDigits,
|
||||
int maxFraDigits, int minFraDigits) {
|
||||
|
||||
char grouping = symbols.getGroupingSeparator();
|
||||
char zero = symbols.getZeroDigit();
|
||||
int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
|
||||
char grouping = symbols.getGroupingSeparator();
|
||||
|
||||
char decimal = isCurrencyFormat ?
|
||||
symbols.getMonetaryDecimalSeparator() :
|
||||
symbols.getDecimalSeparator();
|
||||
symbols.getMonetaryDecimalSeparator() :
|
||||
symbols.getDecimalSeparator();
|
||||
|
||||
/* Per bug 4147706, DecimalFormat must respect the sign of numbers which
|
||||
* format as zero. This allows sensible computations and preserves
|
||||
@ -1703,14 +1794,6 @@ public class DecimalFormat extends NumberFormat {
|
||||
digitList.decimalAt = 0; // Normalize
|
||||
}
|
||||
|
||||
if (isNegative) {
|
||||
append(result, negativePrefix, delegate,
|
||||
getNegativePrefixFieldPositions(), Field.SIGN);
|
||||
} else {
|
||||
append(result, positivePrefix, delegate,
|
||||
getPositivePrefixFieldPositions(), Field.SIGN);
|
||||
}
|
||||
|
||||
if (useExponentialNotation) {
|
||||
int iFieldStart = result.length();
|
||||
int iFieldEnd = -1;
|
||||
@ -1719,7 +1802,6 @@ public class DecimalFormat extends NumberFormat {
|
||||
// Minimum integer digits are handled in exponential format by
|
||||
// adjusting the exponent. For example, 0.01234 with 3 minimum
|
||||
// integer digits is "123.4E-4".
|
||||
|
||||
// Maximum integer digits are interpreted as indicating the
|
||||
// repeating range. This is useful for engineering notation, in
|
||||
// which the exponent is restricted to a multiple of 3. For
|
||||
@ -1782,8 +1864,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
fFieldStart = result.length();
|
||||
}
|
||||
result.append((i < digitList.count) ?
|
||||
(char)(digitList.digits[i] + zeroDelta) :
|
||||
zero);
|
||||
(char)(digitList.digits[i] + zeroDelta) :
|
||||
zero);
|
||||
}
|
||||
|
||||
if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
|
||||
@ -1802,17 +1884,17 @@ public class DecimalFormat extends NumberFormat {
|
||||
iFieldEnd = result.length();
|
||||
}
|
||||
delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
|
||||
iFieldStart, iFieldEnd, result);
|
||||
iFieldStart, iFieldEnd, result);
|
||||
if (addedDecimalSeparator) {
|
||||
delegate.formatted(Field.DECIMAL_SEPARATOR,
|
||||
Field.DECIMAL_SEPARATOR,
|
||||
iFieldEnd, fFieldStart, result);
|
||||
Field.DECIMAL_SEPARATOR,
|
||||
iFieldEnd, fFieldStart, result);
|
||||
}
|
||||
if (fFieldStart == -1) {
|
||||
fFieldStart = result.length();
|
||||
}
|
||||
delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
|
||||
fFieldStart, result.length(), result);
|
||||
fFieldStart, result.length(), result);
|
||||
|
||||
// The exponent is output using the pattern-specified minimum
|
||||
// exponent digits. There is no maximum limit to the exponent
|
||||
@ -1823,7 +1905,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
result.append(symbols.getExponentSeparator());
|
||||
|
||||
delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
|
||||
fieldStart, result.length(), result);
|
||||
fieldStart, result.length(), result);
|
||||
|
||||
// For zero values, we force the exponent to zero. We
|
||||
// must do this here, and not earlier, because the value
|
||||
@ -1838,7 +1920,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
fieldStart = result.length();
|
||||
result.append(symbols.getMinusSign());
|
||||
delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
|
||||
fieldStart, result.length(), result);
|
||||
fieldStart, result.length(), result);
|
||||
}
|
||||
digitList.set(negativeExponent, exponent);
|
||||
|
||||
@ -1849,10 +1931,10 @@ public class DecimalFormat extends NumberFormat {
|
||||
}
|
||||
for (int i=0; i<digitList.decimalAt; ++i) {
|
||||
result.append((i < digitList.count) ?
|
||||
(char)(digitList.digits[i] + zeroDelta) : zero);
|
||||
(char)(digitList.digits[i] + zeroDelta) : zero);
|
||||
}
|
||||
delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
|
||||
result.length(), result);
|
||||
result.length(), result);
|
||||
} else {
|
||||
int iFieldStart = result.length();
|
||||
|
||||
@ -1889,19 +1971,19 @@ public class DecimalFormat extends NumberFormat {
|
||||
// grouping separator if i==0 though; that's at the end of
|
||||
// the integer part.
|
||||
if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
|
||||
(i % groupingSize == 0)) {
|
||||
(i % groupingSize == 0)) {
|
||||
int gStart = result.length();
|
||||
result.append(grouping);
|
||||
delegate.formatted(Field.GROUPING_SEPARATOR,
|
||||
Field.GROUPING_SEPARATOR, gStart,
|
||||
result.length(), result);
|
||||
Field.GROUPING_SEPARATOR, gStart,
|
||||
result.length(), result);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether or not there are any printable fractional
|
||||
// digits. If we've used up the digits we know there aren't.
|
||||
boolean fractionPresent = (minFraDigits > 0) ||
|
||||
(!isInteger && digitIndex < digitList.count);
|
||||
(!isInteger && digitIndex < digitList.count);
|
||||
|
||||
// If there is no fraction present, and we haven't printed any
|
||||
// integer digits, then print a zero. Otherwise we won't print
|
||||
@ -1911,7 +1993,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
}
|
||||
|
||||
delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
|
||||
iFieldStart, result.length(), result);
|
||||
iFieldStart, result.length(), result);
|
||||
|
||||
// Output the decimal separator if we always do so.
|
||||
int sStart = result.length();
|
||||
@ -1921,8 +2003,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
|
||||
if (sStart != result.length()) {
|
||||
delegate.formatted(Field.DECIMAL_SEPARATOR,
|
||||
Field.DECIMAL_SEPARATOR,
|
||||
sStart, result.length(), result);
|
||||
Field.DECIMAL_SEPARATOR,
|
||||
sStart, result.length(), result);
|
||||
}
|
||||
int fFieldStart = result.length();
|
||||
|
||||
@ -1934,7 +2016,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
// we have an integer, so there is no fractional stuff to
|
||||
// display, or we're out of significant digits.
|
||||
if (i >= minFraDigits &&
|
||||
(isInteger || digitIndex >= digitList.count)) {
|
||||
(isInteger || digitIndex >= digitList.count)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1957,18 +2039,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
|
||||
// Record field information for caller.
|
||||
delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
|
||||
fFieldStart, result.length(), result);
|
||||
fFieldStart, result.length(), result);
|
||||
}
|
||||
|
||||
if (isNegative) {
|
||||
append(result, negativeSuffix, delegate,
|
||||
getNegativeSuffixFieldPositions(), Field.SIGN);
|
||||
} else {
|
||||
append(result, positiveSuffix, delegate,
|
||||
getPositiveSuffixFieldPositions(), Field.SIGN);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2209,19 +2281,18 @@ public class DecimalFormat extends NumberFormat {
|
||||
* whether the value was infinite and whether it was positive.
|
||||
*/
|
||||
private final boolean subparse(String text, ParsePosition parsePosition,
|
||||
String positivePrefix, String negativePrefix,
|
||||
DigitList digits, boolean isExponent,
|
||||
boolean status[]) {
|
||||
String positivePrefix, String negativePrefix,
|
||||
DigitList digits, boolean isExponent,
|
||||
boolean status[]) {
|
||||
int position = parsePosition.index;
|
||||
int oldStart = parsePosition.index;
|
||||
int backup;
|
||||
boolean gotPositive, gotNegative;
|
||||
|
||||
// check for positivePrefix; take longest
|
||||
gotPositive = text.regionMatches(position, positivePrefix, 0,
|
||||
positivePrefix.length());
|
||||
positivePrefix.length());
|
||||
gotNegative = text.regionMatches(position, negativePrefix, 0,
|
||||
negativePrefix.length());
|
||||
negativePrefix.length());
|
||||
|
||||
if (gotPositive && gotNegative) {
|
||||
if (positivePrefix.length() > negativePrefix.length()) {
|
||||
@ -2240,10 +2311,75 @@ public class DecimalFormat extends NumberFormat {
|
||||
return false;
|
||||
}
|
||||
|
||||
position = subparseNumber(text, position, digits, true, isExponent, status);
|
||||
if (position == -1) {
|
||||
parsePosition.index = oldStart;
|
||||
parsePosition.errorIndex = oldStart;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for suffix
|
||||
if (!isExponent) {
|
||||
if (gotPositive) {
|
||||
gotPositive = text.regionMatches(position,positiveSuffix,0,
|
||||
positiveSuffix.length());
|
||||
}
|
||||
if (gotNegative) {
|
||||
gotNegative = text.regionMatches(position,negativeSuffix,0,
|
||||
negativeSuffix.length());
|
||||
}
|
||||
|
||||
// If both match, take longest
|
||||
if (gotPositive && gotNegative) {
|
||||
if (positiveSuffix.length() > negativeSuffix.length()) {
|
||||
gotNegative = false;
|
||||
} else if (positiveSuffix.length() < negativeSuffix.length()) {
|
||||
gotPositive = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Fail if neither or both
|
||||
if (gotPositive == gotNegative) {
|
||||
parsePosition.errorIndex = position;
|
||||
return false;
|
||||
}
|
||||
|
||||
parsePosition.index = position +
|
||||
(gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
|
||||
} else {
|
||||
parsePosition.index = position;
|
||||
}
|
||||
|
||||
status[STATUS_POSITIVE] = gotPositive;
|
||||
if (parsePosition.index == oldStart) {
|
||||
parsePosition.errorIndex = position;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a number from the given {@code text}. The text is parsed
|
||||
* beginning at position, until an unparseable character is seen.
|
||||
*
|
||||
* @param text the string to parse
|
||||
* @param position the position at which parsing begins
|
||||
* @param digits the DigitList to set to the parsed value
|
||||
* @param checkExponent whether to check for exponential number
|
||||
* @param isExponent if the exponential part is encountered
|
||||
* @param status upon return contains boolean status flags indicating
|
||||
* whether the value is infinite and whether it is
|
||||
* positive
|
||||
* @return returns the position of the first unparseable character or
|
||||
* -1 in case of no valid number parsed
|
||||
*/
|
||||
int subparseNumber(String text, int position,
|
||||
DigitList digits, boolean checkExponent,
|
||||
boolean isExponent, boolean status[]) {
|
||||
// process digits or Inf, find decimal position
|
||||
status[STATUS_INFINITE] = false;
|
||||
if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
|
||||
symbols.getInfinity().length())) {
|
||||
symbols.getInfinity().length())) {
|
||||
position += symbols.getInfinity().length();
|
||||
status[STATUS_INFINITE] = true;
|
||||
} else {
|
||||
@ -2257,8 +2393,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
digits.decimalAt = digits.count = 0;
|
||||
char zero = symbols.getZeroDigit();
|
||||
char decimal = isCurrencyFormat ?
|
||||
symbols.getMonetaryDecimalSeparator() :
|
||||
symbols.getDecimalSeparator();
|
||||
symbols.getMonetaryDecimalSeparator() :
|
||||
symbols.getDecimalSeparator();
|
||||
char grouping = symbols.getGroupingSeparator();
|
||||
String exponentString = symbols.getExponentSeparator();
|
||||
boolean sawDecimal = false;
|
||||
@ -2270,7 +2406,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
// pin when the maximum allowable digits is reached.
|
||||
int digitCount = 0;
|
||||
|
||||
backup = -1;
|
||||
int backup = -1;
|
||||
for (; position < text.length(); ++position) {
|
||||
char ch = text.charAt(position);
|
||||
|
||||
@ -2334,15 +2470,15 @@ public class DecimalFormat extends NumberFormat {
|
||||
// require that they be followed by a digit. Otherwise
|
||||
// we backup and reprocess them.
|
||||
backup = position;
|
||||
} else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
|
||||
&& !sawExponent) {
|
||||
} else if (checkExponent && !isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
|
||||
&& !sawExponent) {
|
||||
// Process the exponent by recursively calling this method.
|
||||
ParsePosition pos = new ParsePosition(position + exponentString.length());
|
||||
ParsePosition pos = new ParsePosition(position + exponentString.length());
|
||||
boolean[] stat = new boolean[STATUS_LENGTH];
|
||||
DigitList exponentDigits = new DigitList();
|
||||
|
||||
if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
|
||||
exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
|
||||
exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
|
||||
position = pos.index; // Advance past the exponent
|
||||
exponent = (int)exponentDigits.getLong();
|
||||
if (!stat[STATUS_POSITIVE]) {
|
||||
@ -2373,50 +2509,11 @@ public class DecimalFormat extends NumberFormat {
|
||||
// parse "$" with pattern "$#0.00". (return index 0 and error
|
||||
// index 1).
|
||||
if (!sawDigit && digitCount == 0) {
|
||||
parsePosition.index = oldStart;
|
||||
parsePosition.errorIndex = oldStart;
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
|
||||
// check for suffix
|
||||
if (!isExponent) {
|
||||
if (gotPositive) {
|
||||
gotPositive = text.regionMatches(position,positiveSuffix,0,
|
||||
positiveSuffix.length());
|
||||
}
|
||||
if (gotNegative) {
|
||||
gotNegative = text.regionMatches(position,negativeSuffix,0,
|
||||
negativeSuffix.length());
|
||||
}
|
||||
|
||||
// if both match, take longest
|
||||
if (gotPositive && gotNegative) {
|
||||
if (positiveSuffix.length() > negativeSuffix.length()) {
|
||||
gotNegative = false;
|
||||
} else if (positiveSuffix.length() < negativeSuffix.length()) {
|
||||
gotPositive = false;
|
||||
}
|
||||
}
|
||||
|
||||
// fail if neither or both
|
||||
if (gotPositive == gotNegative) {
|
||||
parsePosition.errorIndex = position;
|
||||
return false;
|
||||
}
|
||||
|
||||
parsePosition.index = position +
|
||||
(gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
|
||||
} else {
|
||||
parsePosition.index = position;
|
||||
}
|
||||
|
||||
status[STATUS_POSITIVE] = gotPositive;
|
||||
if (parsePosition.index == oldStart) {
|
||||
parsePosition.errorIndex = position;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -47,13 +47,11 @@ import java.math.RoundingMode;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Currency;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.spi.LocaleServiceProvider;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleServiceProviderPool;
|
||||
|
||||
@ -112,9 +110,12 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
|
||||
* Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
|
||||
* normal number format. Use <code>getIntegerInstance</code> to get an
|
||||
* integer number format. Use <code>getCurrencyInstance</code> to get the
|
||||
* currency number format. And use <code>getPercentInstance</code> to get a
|
||||
* format for displaying percentages. With this format, a fraction like
|
||||
* 0.53 is displayed as 53%.
|
||||
* currency number format. Use {@code getCompactNumberInstance} to get the
|
||||
* compact number format to format a number in shorter form. For example,
|
||||
* {@code 2000} can be formatted as {@code "2K"} in
|
||||
* {@link java.util.Locale#US US locale}. Use <code>getPercentInstance</code>
|
||||
* to get a format for displaying percentages. With this format, a fraction
|
||||
* like 0.53 is displayed as 53%.
|
||||
*
|
||||
* <p>
|
||||
* You can also control the display of numbers with such methods as
|
||||
@ -122,9 +123,10 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
|
||||
* If you want even more control over the format or parsing,
|
||||
* or want to give your users more control,
|
||||
* you can try casting the <code>NumberFormat</code> you get from the factory methods
|
||||
* to a <code>DecimalFormat</code>. This will work for the vast majority
|
||||
* of locales; just remember to put it in a <code>try</code> block in case you
|
||||
* encounter an unusual one.
|
||||
* to a {@code DecimalFormat} or {@code CompactNumberFormat} depending on
|
||||
* the factory method used. This will work for the vast majority of locales;
|
||||
* just remember to put it in a <code>try</code> block in case you encounter
|
||||
* an unusual one.
|
||||
*
|
||||
* <p>
|
||||
* NumberFormat and DecimalFormat are designed such that some controls
|
||||
@ -201,6 +203,7 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
|
||||
*
|
||||
* @see DecimalFormat
|
||||
* @see ChoiceFormat
|
||||
* @see CompactNumberFormat
|
||||
* @author Mark Davis
|
||||
* @author Helena Shih
|
||||
* @since 1.1
|
||||
@ -472,7 +475,7 @@ public abstract class NumberFormat extends Format {
|
||||
* formatting
|
||||
*/
|
||||
public static final NumberFormat getInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -485,7 +488,7 @@ public abstract class NumberFormat extends Format {
|
||||
* formatting
|
||||
*/
|
||||
public static NumberFormat getInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, NUMBERSTYLE);
|
||||
return getInstance(inLocale, null, NUMBERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -501,7 +504,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @see java.util.Locale.Category#FORMAT
|
||||
*/
|
||||
public static final NumberFormat getNumberInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -512,7 +515,7 @@ public abstract class NumberFormat extends Format {
|
||||
* formatting
|
||||
*/
|
||||
public static NumberFormat getNumberInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, NUMBERSTYLE);
|
||||
return getInstance(inLocale, null, NUMBERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -534,7 +537,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @since 1.4
|
||||
*/
|
||||
public static final NumberFormat getIntegerInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, INTEGERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -551,7 +554,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @since 1.4
|
||||
*/
|
||||
public static NumberFormat getIntegerInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, INTEGERSTYLE);
|
||||
return getInstance(inLocale, null, INTEGERSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -566,7 +569,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @see java.util.Locale.Category#FORMAT
|
||||
*/
|
||||
public static final NumberFormat getCurrencyInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, CURRENCYSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -576,7 +579,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @return the {@code NumberFormat} instance for currency formatting
|
||||
*/
|
||||
public static NumberFormat getCurrencyInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, CURRENCYSTYLE);
|
||||
return getInstance(inLocale, null, CURRENCYSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,7 +594,7 @@ public abstract class NumberFormat extends Format {
|
||||
* @see java.util.Locale.Category#FORMAT
|
||||
*/
|
||||
public static final NumberFormat getPercentInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, PERCENTSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -601,14 +604,14 @@ public abstract class NumberFormat extends Format {
|
||||
* @return the {@code NumberFormat} instance for percentage formatting
|
||||
*/
|
||||
public static NumberFormat getPercentInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, PERCENTSTYLE);
|
||||
return getInstance(inLocale, null, PERCENTSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scientific format for the current default locale.
|
||||
*/
|
||||
/*public*/ final static NumberFormat getScientificInstance() {
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
|
||||
return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, SCIENTIFICSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -617,7 +620,50 @@ public abstract class NumberFormat extends Format {
|
||||
* @param inLocale the desired locale
|
||||
*/
|
||||
/*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
|
||||
return getInstance(inLocale, SCIENTIFICSTYLE);
|
||||
return getInstance(inLocale, null, SCIENTIFICSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a compact number format for the default
|
||||
* {@link java.util.Locale.Category#FORMAT FORMAT} locale with
|
||||
* {@link NumberFormat.Style#SHORT "SHORT"} format style.
|
||||
*
|
||||
* @return A {@code NumberFormat} instance for compact number
|
||||
* formatting
|
||||
*
|
||||
* @see CompactNumberFormat
|
||||
* @see NumberFormat.Style
|
||||
* @see java.util.Locale#getDefault(java.util.Locale.Category)
|
||||
* @see java.util.Locale.Category#FORMAT
|
||||
* @since 12
|
||||
*/
|
||||
public static NumberFormat getCompactNumberInstance() {
|
||||
return getInstance(Locale.getDefault(
|
||||
Locale.Category.FORMAT), NumberFormat.Style.SHORT, COMPACTSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a compact number format for the specified {@link java.util.Locale locale}
|
||||
* and {@link NumberFormat.Style formatStyle}.
|
||||
*
|
||||
* @param locale the desired locale
|
||||
* @param formatStyle the style for formatting a number
|
||||
* @return A {@code NumberFormat} instance for compact number
|
||||
* formatting
|
||||
* @throws NullPointerException if {@code locale} or {@code formatStyle}
|
||||
* is {@code null}
|
||||
*
|
||||
* @see CompactNumberFormat
|
||||
* @see NumberFormat.Style
|
||||
* @see java.util.Locale
|
||||
* @since 12
|
||||
*/
|
||||
public static NumberFormat getCompactNumberInstance(Locale locale,
|
||||
NumberFormat.Style formatStyle) {
|
||||
|
||||
Objects.requireNonNull(locale);
|
||||
Objects.requireNonNull(formatStyle);
|
||||
return getInstance(locale, formatStyle, COMPACTSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -900,20 +946,22 @@ public abstract class NumberFormat extends Format {
|
||||
// =======================privates===============================
|
||||
|
||||
private static NumberFormat getInstance(Locale desiredLocale,
|
||||
int choice) {
|
||||
Style formatStyle, int choice) {
|
||||
LocaleProviderAdapter adapter;
|
||||
adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
|
||||
desiredLocale);
|
||||
NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
|
||||
desiredLocale);
|
||||
NumberFormat numberFormat = getInstance(adapter, desiredLocale,
|
||||
formatStyle, choice);
|
||||
if (numberFormat == null) {
|
||||
numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
|
||||
desiredLocale, choice);
|
||||
desiredLocale, formatStyle, choice);
|
||||
}
|
||||
return numberFormat;
|
||||
}
|
||||
|
||||
private static NumberFormat getInstance(LocaleProviderAdapter adapter,
|
||||
Locale locale, int choice) {
|
||||
Locale locale, Style formatStyle,
|
||||
int choice) {
|
||||
NumberFormatProvider provider = adapter.getNumberFormatProvider();
|
||||
NumberFormat numberFormat = null;
|
||||
switch (choice) {
|
||||
@ -929,6 +977,9 @@ public abstract class NumberFormat extends Format {
|
||||
case INTEGERSTYLE:
|
||||
numberFormat = provider.getIntegerInstance(locale);
|
||||
break;
|
||||
case COMPACTSTYLE:
|
||||
numberFormat = provider.getCompactNumberInstance(locale, formatStyle);
|
||||
break;
|
||||
}
|
||||
return numberFormat;
|
||||
}
|
||||
@ -1001,6 +1052,7 @@ public abstract class NumberFormat extends Format {
|
||||
private static final int PERCENTSTYLE = 2;
|
||||
private static final int SCIENTIFICSTYLE = 3;
|
||||
private static final int INTEGERSTYLE = 4;
|
||||
private static final int COMPACTSTYLE = 5;
|
||||
|
||||
/**
|
||||
* True if the grouping (i.e. thousands) separator is used when
|
||||
@ -1276,5 +1328,43 @@ public abstract class NumberFormat extends Format {
|
||||
* Constant identifying the exponent sign field.
|
||||
*/
|
||||
public static final Field EXPONENT_SIGN = new Field("exponent sign");
|
||||
|
||||
/**
|
||||
* Constant identifying the prefix field.
|
||||
*
|
||||
* @since 12
|
||||
*/
|
||||
public static final Field PREFIX = new Field("prefix");
|
||||
|
||||
/**
|
||||
* Constant identifying the suffix field.
|
||||
*
|
||||
* @since 12
|
||||
*/
|
||||
public static final Field SUFFIX = new Field("suffix");
|
||||
}
|
||||
|
||||
/**
|
||||
* A number format style.
|
||||
* <p>
|
||||
* {@code Style} is an enum which represents the style for formatting
|
||||
* a number within a given {@code NumberFormat} instance.
|
||||
*
|
||||
* @see CompactNumberFormat
|
||||
* @see NumberFormat#getCompactNumberInstance(Locale, Style)
|
||||
* @since 12
|
||||
*/
|
||||
public enum Style {
|
||||
|
||||
/**
|
||||
* The {@code SHORT} number format style.
|
||||
*/
|
||||
SHORT,
|
||||
|
||||
/**
|
||||
* The {@code LONG} number format style.
|
||||
*/
|
||||
LONG
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -110,4 +110,37 @@ public abstract class NumberFormatProvider extends LocaleServiceProvider {
|
||||
* @see java.text.NumberFormat#getPercentInstance(java.util.Locale)
|
||||
*/
|
||||
public abstract NumberFormat getPercentInstance(Locale locale);
|
||||
|
||||
/**
|
||||
* Returns a new {@code NumberFormat} instance which formats
|
||||
* a number in its compact form for the specified
|
||||
* {@code locale} and {@code formatStyle}.
|
||||
*
|
||||
* @implSpec The default implementation of this method throws
|
||||
* {@code UnSupportedOperationException}. Overriding the implementation
|
||||
* of this method returns the compact number formatter instance
|
||||
* of the given {@code locale} with specified {@code formatStyle}.
|
||||
*
|
||||
* @param locale the desired locale
|
||||
* @param formatStyle the style for formatting a number
|
||||
* @throws NullPointerException if {@code locale} or {@code formatStyle}
|
||||
* is {@code null}
|
||||
* @throws IllegalArgumentException if {@code locale} is not
|
||||
* one of the locales returned from
|
||||
* {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
|
||||
* getAvailableLocales()}.
|
||||
* @return a compact number formatter
|
||||
*
|
||||
* @see java.text.NumberFormat#getCompactNumberInstance(Locale,
|
||||
* NumberFormat.Style)
|
||||
* @since 12
|
||||
*/
|
||||
public NumberFormat getCompactNumberInstance(Locale locale,
|
||||
NumberFormat.Style formatStyle) {
|
||||
throw new UnsupportedOperationException(
|
||||
"The " + this.getClass().getName() + " should override this"
|
||||
+ " method to return compact number format instance of "
|
||||
+ locale + " locale and " + formatStyle + " style.");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -796,6 +796,44 @@ public class FormatData extends ParallelListResourceBundle {
|
||||
"NaN",
|
||||
}
|
||||
},
|
||||
{ "short.CompactNumberPatterns",
|
||||
new String[] {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"0K",
|
||||
"00K",
|
||||
"000K",
|
||||
"0M",
|
||||
"00M",
|
||||
"000M",
|
||||
"0B",
|
||||
"00B",
|
||||
"000B",
|
||||
"0T",
|
||||
"00T",
|
||||
"000T",
|
||||
}
|
||||
},
|
||||
{ "long.CompactNumberPatterns",
|
||||
new String[] {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"0 thousand",
|
||||
"00 thousand",
|
||||
"000 thousand",
|
||||
"0 million",
|
||||
"00 million",
|
||||
"000 million",
|
||||
"0 billion",
|
||||
"00 billion",
|
||||
"000 billion",
|
||||
"0 trillion",
|
||||
"00 trillion",
|
||||
"000 trillion",
|
||||
}
|
||||
},
|
||||
{ "TimePatterns",
|
||||
new String[] {
|
||||
"h:mm:ss a z", // full time pattern
|
||||
|
@ -43,6 +43,7 @@ package sun.util.locale.provider;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
@ -88,6 +89,7 @@ public class LocaleResources {
|
||||
private static final String ZONE_IDS_CACHEKEY = "ZID";
|
||||
private static final String CALENDAR_NAMES = "CALN.";
|
||||
private static final String NUMBER_PATTERNS_CACHEKEY = "NP";
|
||||
private static final String COMPACT_NUMBER_PATTERNS_CACHEKEY = "CNP";
|
||||
private static final String DATE_TIME_PATTERN = "DTP.";
|
||||
|
||||
// TimeZoneNamesBundle exemplar city prefix
|
||||
@ -478,6 +480,32 @@ public class LocaleResources {
|
||||
return numberPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compact number format patterns.
|
||||
* @param formatStyle the style for formatting a number
|
||||
* @return an array of compact number patterns
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public String[] getCNPatterns(NumberFormat.Style formatStyle) {
|
||||
|
||||
Objects.requireNonNull(formatStyle);
|
||||
String[] compactNumberPatterns = null;
|
||||
removeEmptyReferences();
|
||||
String width = (formatStyle == NumberFormat.Style.LONG) ? "long" : "short";
|
||||
String cacheKey = width + "." + COMPACT_NUMBER_PATTERNS_CACHEKEY;
|
||||
ResourceReference data = cache.get(cacheKey);
|
||||
if (data == null || ((compactNumberPatterns
|
||||
= (String[]) data.get()) == null)) {
|
||||
ResourceBundle resource = localeData.getNumberFormatData(locale);
|
||||
compactNumberPatterns = (String[]) resource
|
||||
.getObject(width + ".CompactNumberPatterns");
|
||||
cache.put(cacheKey, new ResourceReference(cacheKey,
|
||||
(Object) compactNumberPatterns, referenceQueue));
|
||||
}
|
||||
return compactNumberPatterns;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the FormatData resource bundle of this LocaleResources.
|
||||
* The FormatData should be used only for accessing extra
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -40,12 +40,14 @@
|
||||
|
||||
package sun.util.locale.provider;
|
||||
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.spi.NumberFormatProvider;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -225,6 +227,49 @@ public class NumberFormatProviderImpl extends NumberFormatProvider implements Av
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@code NumberFormat} instance which formats
|
||||
* a number in its compact form for the specified
|
||||
* {@code locale} and {@code formatStyle}.
|
||||
*
|
||||
* @param locale the desired locale
|
||||
* @param formatStyle the style for formatting a number
|
||||
* @throws NullPointerException if {@code locale} or {@code formatStyle}
|
||||
* is {@code null}
|
||||
* @throws IllegalArgumentException if {@code locale} isn't
|
||||
* one of the locales returned from
|
||||
* {@link java.util.spi.LocaleServiceProvider#getAvailableLocales()
|
||||
* getAvailableLocales()}.
|
||||
* @return a compact number formatter
|
||||
*
|
||||
* @see java.text.NumberFormat#getCompactNumberInstance(Locale,
|
||||
* NumberFormat.Style)
|
||||
* @since 12
|
||||
*/
|
||||
@Override
|
||||
public NumberFormat getCompactNumberInstance(Locale locale,
|
||||
NumberFormat.Style formatStyle) {
|
||||
|
||||
Objects.requireNonNull(locale);
|
||||
Objects.requireNonNull(formatStyle);
|
||||
|
||||
// Check for region override
|
||||
Locale override = locale.getUnicodeLocaleType("nu") == null
|
||||
? CalendarDataUtility.findRegionOverride(locale)
|
||||
: locale;
|
||||
|
||||
LocaleProviderAdapter adapter = LocaleProviderAdapter.forType(type);
|
||||
LocaleResources resource = adapter.getLocaleResources(override);
|
||||
|
||||
String[] numberPatterns = resource.getNumberPatterns();
|
||||
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(override);
|
||||
String[] cnPatterns = resource.getCNPatterns(formatStyle);
|
||||
|
||||
CompactNumberFormat format = new CompactNumberFormat(numberPatterns[0],
|
||||
symbols, cnPatterns);
|
||||
return format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAvailableLanguageTags() {
|
||||
return langtags;
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
class CompactFormatAndParseHelper {
|
||||
|
||||
static void testFormat(NumberFormat cnf, Object number,
|
||||
String expected) {
|
||||
String result = cnf.format(number);
|
||||
assertEquals(result, expected, "Incorrect formatting of the number '"
|
||||
+ number + "'");
|
||||
}
|
||||
|
||||
static void testParse(NumberFormat cnf, String parseString,
|
||||
Number expected, ParsePosition position, Class<? extends Number> returnType) throws ParseException {
|
||||
|
||||
Number number;
|
||||
if (position == null) {
|
||||
number = cnf.parse(parseString);
|
||||
} else {
|
||||
number = cnf.parse(parseString, position);
|
||||
}
|
||||
|
||||
if (returnType != null) {
|
||||
assertEquals(number.getClass(), returnType, "Incorrect return type for string" + parseString);
|
||||
}
|
||||
|
||||
if (number instanceof Double) {
|
||||
assertEquals(number.doubleValue(), (double) expected,
|
||||
"Incorrect parsing of the string '" + parseString + "'");
|
||||
} else if (number instanceof Long) {
|
||||
assertEquals(number.longValue(), (long) expected,
|
||||
"Incorrect parsing of the string '" + parseString + "'");
|
||||
} else if (number instanceof BigDecimal) {
|
||||
BigDecimal num = (BigDecimal) number;
|
||||
assertEquals(num, (BigDecimal) expected,
|
||||
"Incorrect parsing of the string '" + parseString + "'");
|
||||
} else {
|
||||
assertEquals(number, expected, "Incorrect parsing of the string '"
|
||||
+ parseString + "'");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the rounding of formatted number in compact number formatting
|
||||
* @run testng/othervm TestCNFRounding
|
||||
*/
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import static org.testng.Assert.*;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestCNFRounding {
|
||||
|
||||
private static final List<RoundingMode> MODES = List.of(
|
||||
RoundingMode.HALF_EVEN,
|
||||
RoundingMode.HALF_UP,
|
||||
RoundingMode.HALF_DOWN,
|
||||
RoundingMode.UP,
|
||||
RoundingMode.DOWN,
|
||||
RoundingMode.CEILING,
|
||||
RoundingMode.FLOOR);
|
||||
|
||||
@DataProvider(name = "roundingData")
|
||||
Object[][] roundingData() {
|
||||
return new Object[][]{
|
||||
// Number, half_even, half_up, half_down, up, down, ceiling, floor
|
||||
{5500, new String[]{"6K", "6K", "5K", "6K", "5K", "6K", "5K"}},
|
||||
{2500, new String[]{"2K", "3K", "2K", "3K", "2K", "3K", "2K"}},
|
||||
{1600, new String[]{"2K", "2K", "2K", "2K", "1K", "2K", "1K"}},
|
||||
{1100, new String[]{"1K", "1K", "1K", "2K", "1K", "2K", "1K"}},
|
||||
{1000, new String[]{"1K", "1K", "1K", "1K", "1K", "1K", "1K"}},
|
||||
{-1000, new String[]{"-1K", "-1K", "-1K", "-1K", "-1K", "-1K", "-1K"}},
|
||||
{-1100, new String[]{"-1K", "-1K", "-1K", "-2K", "-1K", "-1K", "-2K"}},
|
||||
{-1600, new String[]{"-2K", "-2K", "-2K", "-2K", "-1K", "-1K", "-2K"}},
|
||||
{-2500, new String[]{"-2K", "-3K", "-2K", "-3K", "-2K", "-2K", "-3K"}},
|
||||
{-5500, new String[]{"-6K", "-6K", "-5K", "-6K", "-5K", "-5K", "-6K"}},
|
||||
{5501, new String[]{"6K", "6K", "6K", "6K", "5K", "6K", "5K"}},
|
||||
{-5501, new String[]{"-6K", "-6K", "-6K", "-6K", "-5K", "-5K", "-6K"}},
|
||||
{1001, new String[]{"1K", "1K", "1K", "2K", "1K", "2K", "1K"}},
|
||||
{-1001, new String[]{"-1K", "-1K", "-1K", "-2K", "-1K", "-1K", "-2K"}},
|
||||
{4501, new String[]{"5K", "5K", "5K", "5K", "4K", "5K", "4K"}},
|
||||
{-4501, new String[]{"-5K", "-5K", "-5K", "-5K", "-4K", "-4K", "-5K"}},
|
||||
{4500, new String[]{"4K", "5K", "4K", "5K", "4K", "5K", "4K"}},
|
||||
{-4500, new String[]{"-4K", "-5K", "-4K", "-5K", "-4K", "-4K", "-5K"}},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "roundingFract")
|
||||
Object[][] roundingFract() {
|
||||
return new Object[][]{
|
||||
// Number, half_even, half_up, half_down, up, down, ceiling, floor
|
||||
{5550, new String[]{"5.5K", "5.5K", "5.5K", "5.6K", "5.5K", "5.6K", "5.5K"}},
|
||||
{2550, new String[]{"2.5K", "2.5K", "2.5K", "2.6K", "2.5K", "2.6K", "2.5K"}},
|
||||
{1660, new String[]{"1.7K", "1.7K", "1.7K", "1.7K", "1.6K", "1.7K", "1.6K"}},
|
||||
{1110, new String[]{"1.1K", "1.1K", "1.1K", "1.2K", "1.1K", "1.2K", "1.1K"}},
|
||||
{1000, new String[]{"1.0K", "1.0K", "1.0K", "1.0K", "1.0K", "1.0K", "1.0K"}},
|
||||
{-1000, new String[]{"-1.0K", "-1.0K", "-1.0K", "-1.0K", "-1.0K", "-1.0K", "-1.0K"}},
|
||||
{-1110, new String[]{"-1.1K", "-1.1K", "-1.1K", "-1.2K", "-1.1K", "-1.1K", "-1.2K"}},
|
||||
{-1660, new String[]{"-1.7K", "-1.7K", "-1.7K", "-1.7K", "-1.6K", "-1.6K", "-1.7K"}},
|
||||
{-2550, new String[]{"-2.5K", "-2.5K", "-2.5K", "-2.6K", "-2.5K", "-2.5K", "-2.6K"}},
|
||||
{-5550, new String[]{"-5.5K", "-5.5K", "-5.5K", "-5.6K", "-5.5K", "-5.5K", "-5.6K"}},
|
||||
{5551, new String[]{"5.6K", "5.6K", "5.6K", "5.6K", "5.5K", "5.6K", "5.5K"}},
|
||||
{-5551, new String[]{"-5.6K", "-5.6K", "-5.6K", "-5.6K", "-5.5K", "-5.5K", "-5.6K"}},
|
||||
{1001, new String[]{"1.0K", "1.0K", "1.0K", "1.1K", "1.0K", "1.1K", "1.0K"}},
|
||||
{-1001, new String[]{"-1.0K", "-1.0K", "-1.0K", "-1.1K", "-1.0K", "-1.0K", "-1.1K"}},
|
||||
{4551, new String[]{"4.6K", "4.6K", "4.6K", "4.6K", "4.5K", "4.6K", "4.5K"}},
|
||||
{-4551, new String[]{"-4.6K", "-4.6K", "-4.6K", "-4.6K", "-4.5K", "-4.5K", "-4.6K"}},
|
||||
{4500, new String[]{"4.5K", "4.5K", "4.5K", "4.5K", "4.5K", "4.5K", "4.5K"}},
|
||||
{-4500, new String[]{"-4.5K", "-4.5K", "-4.5K", "-4.5K", "-4.5K", "-4.5K", "-4.5K"}},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "rounding2Fract")
|
||||
Object[][] rounding2Fract() {
|
||||
return new Object[][]{
|
||||
// Number, half_even, half_up, half_down
|
||||
{1115, new String[]{"1.11K", "1.11K", "1.11K"}},
|
||||
{1125, new String[]{"1.12K", "1.13K", "1.12K"}},
|
||||
{1135, new String[]{"1.14K", "1.14K", "1.14K"}},
|
||||
{3115, new String[]{"3.12K", "3.12K", "3.12K"}},
|
||||
{3125, new String[]{"3.12K", "3.13K", "3.12K"}},
|
||||
{3135, new String[]{"3.13K", "3.13K", "3.13K"}},
|
||||
{6865, new String[]{"6.87K", "6.87K", "6.87K"}},
|
||||
{6875, new String[]{"6.88K", "6.88K", "6.87K"}},
|
||||
{6885, new String[]{"6.88K", "6.88K", "6.88K"}},
|
||||
{3124, new String[]{"3.12K", "3.12K", "3.12K"}},
|
||||
{3126, new String[]{"3.13K", "3.13K", "3.13K"}},
|
||||
{3128, new String[]{"3.13K", "3.13K", "3.13K"}},
|
||||
{6864, new String[]{"6.86K", "6.86K", "6.86K"}},
|
||||
{6865, new String[]{"6.87K", "6.87K", "6.87K"}},
|
||||
{6868, new String[]{"6.87K", "6.87K", "6.87K"}},
|
||||
{4685, new String[]{"4.68K", "4.68K", "4.68K"}},
|
||||
{4687, new String[]{"4.69K", "4.69K", "4.69K"}},
|
||||
{4686, new String[]{"4.69K", "4.69K", "4.69K"}},};
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testNullMode() {
|
||||
NumberFormat fmt = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
fmt.setRoundingMode(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRoundingMode() {
|
||||
NumberFormat fmt = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
assertEquals(fmt.getRoundingMode(), RoundingMode.HALF_EVEN,
|
||||
"Default RoundingMode should be " + RoundingMode.HALF_EVEN);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "roundingData")
|
||||
public void testRounding(Object number, String[] expected) {
|
||||
for (int index = 0; index < MODES.size(); index++) {
|
||||
testRoundingMode(number, expected[index], 0, MODES.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "roundingFract")
|
||||
public void testRoundingFract(Object number, String[] expected) {
|
||||
for (int index = 0; index < MODES.size(); index++) {
|
||||
testRoundingMode(number, expected[index], 1, MODES.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "rounding2Fract")
|
||||
public void testRounding2Fract(Object number, String[] expected) {
|
||||
List<RoundingMode> rModes = List.of(RoundingMode.HALF_EVEN,
|
||||
RoundingMode.HALF_UP, RoundingMode.HALF_DOWN);
|
||||
for (int index = 0; index < rModes.size(); index++) {
|
||||
testRoundingMode(number, expected[index], 2, rModes.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
private void testRoundingMode(Object number, String expected,
|
||||
int fraction, RoundingMode rounding) {
|
||||
NumberFormat fmt = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
fmt.setRoundingMode(rounding);
|
||||
assertEquals(fmt.getRoundingMode(), rounding,
|
||||
"RoundingMode set is not returned by getRoundingMode");
|
||||
|
||||
fmt.setMinimumFractionDigits(fraction);
|
||||
String result = fmt.format(number);
|
||||
assertEquals(result, expected, "Incorrect formatting of number "
|
||||
+ number + " using rounding mode: " + rounding);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,589 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the functioning of compact number format
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestCompactNumber
|
||||
*/
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
import static org.testng.Assert.*;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestCompactNumber {
|
||||
|
||||
private static final NumberFormat FORMAT_DZ_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("dz"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_EN_US_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_EN_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_HI_IN_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_JA_JP_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_IT_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("it"), NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_CA_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("ca"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_AS_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("as"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_BRX_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("brx"), NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_SW_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("sw"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_SE_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("se"), NumberFormat.Style.SHORT);
|
||||
|
||||
@DataProvider(name = "format")
|
||||
Object[][] compactFormatData() {
|
||||
return new Object[][]{
|
||||
// compact number format instance, number to format, formatted output
|
||||
{FORMAT_DZ_LONG, 1000.09, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55"
|
||||
+ "\u0FB2\u0F42 \u0F21"},
|
||||
{FORMAT_DZ_LONG, -999.99, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55"
|
||||
+ "\u0FB2\u0F42 \u0F21"},
|
||||
{FORMAT_DZ_LONG, -0.0, "-\u0F20"},
|
||||
{FORMAT_DZ_LONG, 3000L, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55"
|
||||
+ "\u0FB2\u0F42 \u0F23"},
|
||||
{FORMAT_DZ_LONG, new BigInteger("12345678901234567890"), "\u0F51"
|
||||
+ "\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66"
|
||||
+ "\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27"},
|
||||
// negative
|
||||
{FORMAT_DZ_LONG, new BigInteger("-12345678901234567890"), "-\u0F51"
|
||||
+ "\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66"
|
||||
+ "\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27"},
|
||||
{FORMAT_DZ_LONG, new BigDecimal("12345678901234567890.89"), "\u0F51"
|
||||
+ "\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66"
|
||||
+ "\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27"},
|
||||
{FORMAT_DZ_LONG, new BigDecimal("-12345678901234567890.89"), "-\u0F51"
|
||||
+ "\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66"
|
||||
+ "\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27"},
|
||||
// Zeros
|
||||
{FORMAT_EN_US_SHORT, 0, "0"},
|
||||
{FORMAT_EN_US_SHORT, 0.0, "0"},
|
||||
{FORMAT_EN_US_SHORT, -0.0, "-0"},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_EN_US_SHORT, 499, "499"},
|
||||
// Boundary number
|
||||
{FORMAT_EN_US_SHORT, 1000.0, "1K"},
|
||||
// Long
|
||||
{FORMAT_EN_US_SHORT, 3000L, "3K"},
|
||||
{FORMAT_EN_US_SHORT, 30000L, "30K"},
|
||||
{FORMAT_EN_US_SHORT, 300000L, "300K"},
|
||||
{FORMAT_EN_US_SHORT, 3000000L, "3M"},
|
||||
{FORMAT_EN_US_SHORT, 30000000L, "30M"},
|
||||
{FORMAT_EN_US_SHORT, 300000000L, "300M"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000L, "3B"},
|
||||
{FORMAT_EN_US_SHORT, 30000000000L, "30B"},
|
||||
{FORMAT_EN_US_SHORT, 300000000000L, "300B"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000000L, "3T"},
|
||||
{FORMAT_EN_US_SHORT, 30000000000000L, "30T"},
|
||||
{FORMAT_EN_US_SHORT, 300000000000000L, "300T"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000000000L, "3000T"},
|
||||
// Negatives
|
||||
{FORMAT_EN_US_SHORT, -3000L, "-3K"},
|
||||
{FORMAT_EN_US_SHORT, -30000L, "-30K"},
|
||||
{FORMAT_EN_US_SHORT, -300000L, "-300K"},
|
||||
{FORMAT_EN_US_SHORT, -3000000L, "-3M"},
|
||||
{FORMAT_EN_US_SHORT, -30000000L, "-30M"},
|
||||
{FORMAT_EN_US_SHORT, -300000000L, "-300M"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000L, "-3B"},
|
||||
{FORMAT_EN_US_SHORT, -30000000000L, "-30B"},
|
||||
{FORMAT_EN_US_SHORT, -300000000000L, "-300B"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000000L, "-3T"},
|
||||
{FORMAT_EN_US_SHORT, -30000000000000L, "-30T"},
|
||||
{FORMAT_EN_US_SHORT, -300000000000000L, "-300T"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000000000L, "-3000T"},
|
||||
// Double
|
||||
{FORMAT_EN_US_SHORT, 3000.0, "3K"},
|
||||
{FORMAT_EN_US_SHORT, 30000.0, "30K"},
|
||||
{FORMAT_EN_US_SHORT, 300000.0, "300K"},
|
||||
{FORMAT_EN_US_SHORT, 3000000.0, "3M"},
|
||||
{FORMAT_EN_US_SHORT, 30000000.0, "30M"},
|
||||
{FORMAT_EN_US_SHORT, 300000000.0, "300M"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000.0, "3B"},
|
||||
{FORMAT_EN_US_SHORT, 30000000000.0, "30B"},
|
||||
{FORMAT_EN_US_SHORT, 300000000000.0, "300B"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000000.0, "3T"},
|
||||
{FORMAT_EN_US_SHORT, 30000000000000.0, "30T"},
|
||||
{FORMAT_EN_US_SHORT, 300000000000000.0, "300T"},
|
||||
{FORMAT_EN_US_SHORT, 3000000000000000.0, "3000T"},
|
||||
// Negatives
|
||||
{FORMAT_EN_US_SHORT, -3000.0, "-3K"},
|
||||
{FORMAT_EN_US_SHORT, -30000.0, "-30K"},
|
||||
{FORMAT_EN_US_SHORT, -300000.0, "-300K"},
|
||||
{FORMAT_EN_US_SHORT, -3000000.0, "-3M"},
|
||||
{FORMAT_EN_US_SHORT, -30000000.0, "-30M"},
|
||||
{FORMAT_EN_US_SHORT, -300000000.0, "-300M"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000.0, "-3B"},
|
||||
{FORMAT_EN_US_SHORT, -30000000000.0, "-30B"},
|
||||
{FORMAT_EN_US_SHORT, -300000000000.0, "-300B"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000000.0, "-3T"},
|
||||
{FORMAT_EN_US_SHORT, -30000000000000.0, "-30T"},
|
||||
{FORMAT_EN_US_SHORT, -300000000000000.0, "-300T"},
|
||||
{FORMAT_EN_US_SHORT, -3000000000000000.0, "-3000T"},
|
||||
// BigInteger
|
||||
{FORMAT_EN_US_SHORT, new BigInteger("12345678901234567890"),
|
||||
"12345679T"},
|
||||
{FORMAT_EN_US_SHORT, new BigInteger("-12345678901234567890"),
|
||||
"-12345679T"},
|
||||
//BigDecimal
|
||||
{FORMAT_EN_US_SHORT, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679T"},
|
||||
{FORMAT_EN_US_SHORT, new BigDecimal("-12345678901234567890.89"),
|
||||
"-12345679T"},
|
||||
{FORMAT_EN_US_SHORT, new BigDecimal("12345678901234567890123466767.89"),
|
||||
"12345678901234568T"},
|
||||
{FORMAT_EN_US_SHORT, new BigDecimal(
|
||||
"12345678901234567890878732267863209.89"),
|
||||
"12345678901234567890879T"},
|
||||
// number as exponent
|
||||
{FORMAT_EN_US_SHORT, 9.78313E+3, "10K"},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_EN_LONG, 999, "999"},
|
||||
// Round the value and then format
|
||||
{FORMAT_EN_LONG, 999.99, "1 thousand"},
|
||||
// 10 thousand
|
||||
{FORMAT_EN_LONG, 99000, "99 thousand"},
|
||||
// Long path
|
||||
{FORMAT_EN_LONG, 330000, "330 thousand"},
|
||||
// Double path
|
||||
{FORMAT_EN_LONG, 3000.90, "3 thousand"},
|
||||
// BigInteger path
|
||||
{FORMAT_EN_LONG, new BigInteger("12345678901234567890"),
|
||||
"12345679 trillion"},
|
||||
//BigDecimal path
|
||||
{FORMAT_EN_LONG, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679 trillion"},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_HI_IN_LONG, -999, "-999"},
|
||||
// Round the value with 0 fraction digits and format it
|
||||
{FORMAT_HI_IN_LONG, -999.99, "-1 \u0939\u091C\u093C\u093E\u0930"},
|
||||
// 10 thousand
|
||||
{FORMAT_HI_IN_LONG, 99000, "99 \u0939\u091C\u093C\u093E\u0930"},
|
||||
// Long path
|
||||
{FORMAT_HI_IN_LONG, 330000, "3 \u0932\u093E\u0916"},
|
||||
// Double path
|
||||
{FORMAT_HI_IN_LONG, 3000.90, "3 \u0939\u091C\u093C\u093E\u0930"},
|
||||
// BigInteger path
|
||||
{FORMAT_HI_IN_LONG, new BigInteger("12345678901234567890"),
|
||||
"123456789 \u0916\u0930\u092C"},
|
||||
// BigDecimal path
|
||||
{FORMAT_HI_IN_LONG, new BigDecimal("12345678901234567890.89"),
|
||||
"123456789 \u0916\u0930\u092C"},
|
||||
// 1000 does not have any suffix in "ja" locale
|
||||
{FORMAT_JA_JP_SHORT, -999.99, "-1,000"},
|
||||
// 0-9999 does not have any suffix
|
||||
{FORMAT_JA_JP_SHORT, 9999, "9,999"},
|
||||
// 99000/10000 => 9.9\u4E07 rounded to 10\u4E07
|
||||
{FORMAT_JA_JP_SHORT, 99000, "10\u4E07"},
|
||||
// Negative
|
||||
{FORMAT_JA_JP_SHORT, -99000, "-10\u4E07"},
|
||||
// Long path
|
||||
{FORMAT_JA_JP_SHORT, 330000, "33\u4E07"},
|
||||
// Double path
|
||||
{FORMAT_JA_JP_SHORT, 3000.90, "3,001"},
|
||||
// BigInteger path
|
||||
{FORMAT_JA_JP_SHORT, new BigInteger("12345678901234567890"),
|
||||
"12345679\u5146"},
|
||||
// BigDecimal path
|
||||
{FORMAT_JA_JP_SHORT, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679\u5146"},
|
||||
// less than 1000 no suffix
|
||||
{FORMAT_IT_SHORT, 499, "499"},
|
||||
// Boundary number
|
||||
{FORMAT_IT_SHORT, 1000, "1.000"},
|
||||
// Long path
|
||||
{FORMAT_IT_SHORT, 3000000L, "3\u00a0Mln"},
|
||||
// Double path
|
||||
{FORMAT_IT_SHORT, 3000000.0, "3\u00a0Mln"},
|
||||
// BigInteger path
|
||||
{FORMAT_IT_SHORT, new BigInteger("12345678901234567890"),
|
||||
"12345679\u00a0Bln"},
|
||||
// BigDecimal path
|
||||
{FORMAT_IT_SHORT, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679\u00a0Bln"},
|
||||
{FORMAT_CA_LONG, 999, "999"},
|
||||
{FORMAT_CA_LONG, 999.99, "1 miler"},
|
||||
{FORMAT_CA_LONG, 99000, "99 milers"},
|
||||
{FORMAT_CA_LONG, 330000, "330 milers"},
|
||||
{FORMAT_CA_LONG, 3000.90, "3 miler"},
|
||||
{FORMAT_CA_LONG, 1000000, "1 mili\u00f3"},
|
||||
{FORMAT_CA_LONG, new BigInteger("12345678901234567890"),
|
||||
"12345679 bilions"},
|
||||
{FORMAT_CA_LONG, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679 bilions"},
|
||||
{FORMAT_AS_LONG, 5000.0, "\u09eb \u09b9\u09be\u099c\u09be\u09f0"},
|
||||
{FORMAT_AS_LONG, 50000.0, "\u09eb\u09e6 \u09b9\u09be\u099c\u09be\u09f0"},
|
||||
{FORMAT_AS_LONG, 500000.0, "\u09eb \u09b2\u09be\u0996"},
|
||||
{FORMAT_AS_LONG, 5000000.0, "\u09eb \u09a8\u09bf\u09af\u09c1\u09a4"},
|
||||
{FORMAT_AS_LONG, 50000000.0, "\u09eb\u09e6 \u09a8\u09bf\u09af\u09c1\u09a4"},
|
||||
{FORMAT_AS_LONG, 500000000.0, "\u09eb\u09e6\u09e6 \u09a8\u09bf\u09af\u09c1\u09a4"},
|
||||
{FORMAT_AS_LONG, 5000000000.0, "\u09eb \u09b6\u09a4 \u0995\u09cb\u099f\u09bf"},
|
||||
{FORMAT_AS_LONG, 50000000000.0, "\u09eb\u09e6 \u09b6\u09a4 \u0995\u09cb\u099f\u09bf"},
|
||||
{FORMAT_AS_LONG, 500000000000.0, "\u09eb\u09e6\u09e6 \u09b6\u09a4 \u0995\u09cb\u099f\u09bf"},
|
||||
{FORMAT_AS_LONG, 5000000000000.0, "\u09eb \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_AS_LONG, 50000000000000.0, "\u09eb\u09e6 \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_AS_LONG, 500000000000000.0, "\u09eb\u09e6\u09e6 \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_AS_LONG, 5000000000000000.0, "\u09eb\u09e6\u09e6\u09e6 \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_AS_LONG, new BigInteger("12345678901234567890"),
|
||||
"\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ef \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_AS_LONG, new BigDecimal("12345678901234567890123466767.89"),
|
||||
"\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ed\u09ee\u09ef\u09e6\u09e7\u09e8\u09e9\u09ea\u09eb\u09ec\u09ee \u09b6\u09a4 \u09aa\u09f0\u09be\u09f0\u09cd\u09a6\u09cd\u09a7"},
|
||||
{FORMAT_BRX_SHORT, 999, "999"},
|
||||
{FORMAT_BRX_SHORT, 999.99, "1K"},
|
||||
{FORMAT_BRX_SHORT, 99000, "99K"},
|
||||
{FORMAT_BRX_SHORT, 330000, "330K"},
|
||||
{FORMAT_BRX_SHORT, 3000.90, "3K"},
|
||||
{FORMAT_BRX_SHORT, 1000000, "1M"},
|
||||
{FORMAT_BRX_SHORT, new BigInteger("12345678901234567890"),
|
||||
"12345679T"},
|
||||
{FORMAT_BRX_SHORT, new BigDecimal("12345678901234567890.89"),
|
||||
"12345679T"},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_SW_LONG, 499, "499"},
|
||||
// Boundary number
|
||||
{FORMAT_SW_LONG, 1000, "elfu 1"},
|
||||
// Long path
|
||||
{FORMAT_SW_LONG, 3000000L, "milioni 3"},
|
||||
// Long path, negative
|
||||
{FORMAT_SW_LONG, -3000000L, "milioni -3"},
|
||||
// Double path
|
||||
{FORMAT_SW_LONG, 3000000.0, "milioni 3"},
|
||||
// Double path, negative
|
||||
{FORMAT_SW_LONG, -3000000.0, "milioni -3"},
|
||||
// BigInteger path
|
||||
{FORMAT_SW_LONG, new BigInteger("12345678901234567890"),
|
||||
"trilioni 12345679"},
|
||||
// BigDecimal path
|
||||
{FORMAT_SW_LONG, new BigDecimal("12345678901234567890.89"),
|
||||
"trilioni 12345679"},
|
||||
// Positives
|
||||
// No compact form
|
||||
{FORMAT_SE_SHORT, 999, "999"},
|
||||
// Long
|
||||
{FORMAT_SE_SHORT, 8000000L, "8\u00a0mn"},
|
||||
// Double
|
||||
{FORMAT_SE_SHORT, 8000.98, "8\u00a0dt"},
|
||||
// Big integer
|
||||
{FORMAT_SE_SHORT, new BigInteger("12345678901234567890"), "12345679\u00a0bn"},
|
||||
// Big decimal
|
||||
{FORMAT_SE_SHORT, new BigDecimal("12345678901234567890.98"), "12345679\u00a0bn"},
|
||||
// Negatives
|
||||
// No compact form
|
||||
{FORMAT_SE_SHORT, -999, "\u2212999"},
|
||||
// Long
|
||||
{FORMAT_SE_SHORT, -8000000L, "\u22128\u00a0mn"},
|
||||
// Double
|
||||
{FORMAT_SE_SHORT, -8000.98, "\u22128\u00a0dt"},
|
||||
// BigInteger
|
||||
{FORMAT_SE_SHORT, new BigInteger("-12345678901234567890"), "\u221212345679\u00a0bn"},
|
||||
// BigDecimal
|
||||
{FORMAT_SE_SHORT, new BigDecimal("-12345678901234567890.98"), "\u221212345679\u00a0bn"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "parse")
|
||||
Object[][] compactParseData() {
|
||||
return new Object[][]{
|
||||
// compact number format instance, string to parse, parsed number, return type
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F21", 1000L, Long.class},
|
||||
{FORMAT_DZ_LONG, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F23", -3000L, Long.class},
|
||||
{FORMAT_DZ_LONG, "\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62"
|
||||
+ "\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21"
|
||||
+ "\u0F22\u0F23\u0F24\u0F25\u0F27", 1.23457E19, Double.class},
|
||||
{FORMAT_DZ_LONG, "-\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62"
|
||||
+ "\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21"
|
||||
+ "\u0F22\u0F23\u0F24\u0F25\u0F27", -1.23457E19, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-0.0", -0.0, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-0", -0.0, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "0", 0L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "499", 499L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "-499", -499L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "499.89", 499.89, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-499.89", -499.89, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "1K", 1000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "-1K", -1000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "3K", 3000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "17K", 17000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "-17K", -17000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "-3K", -3000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "12345678901234567890", 1.2345678901234567E19, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "12345679T", 1.2345679E19, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-12345679T", -1.2345679E19, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "599.01K", 599010L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "-599.01K", -599010L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "599444444.90T", 5.994444449E20, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-599444444.90T", -5.994444449E20, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "123456789012345.5678K", 123456789012345568L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "17.000K", 17000L, Long.class},
|
||||
{FORMAT_EN_US_SHORT, "123.56678K", 123566.78000, Double.class},
|
||||
{FORMAT_EN_US_SHORT, "-123.56678K", -123566.78000, Double.class},
|
||||
{FORMAT_EN_LONG, "999", 999L, Long.class},
|
||||
{FORMAT_EN_LONG, "1 thousand", 1000L, Long.class},
|
||||
{FORMAT_EN_LONG, "3 thousand", 3000L, Long.class},
|
||||
{FORMAT_EN_LONG, "12345679 trillion", 1.2345679E19, Double.class},
|
||||
{FORMAT_HI_IN_LONG, "999", 999L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "-999", -999L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "1 \u0939\u091C\u093C\u093E\u0930", 1000L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "-1 \u0939\u091C\u093C\u093E\u0930", -1000L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "3 \u0939\u091C\u093C\u093E\u0930", 3000L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "12345679 \u0916\u0930\u092C", 1234567900000000000L, Long.class},
|
||||
{FORMAT_HI_IN_LONG, "-12345679 \u0916\u0930\u092C", -1234567900000000000L, Long.class},
|
||||
{FORMAT_JA_JP_SHORT, "-99", -99L, Long.class},
|
||||
{FORMAT_JA_JP_SHORT, "1\u4E07", 10000L, Long.class},
|
||||
{FORMAT_JA_JP_SHORT, "30\u4E07", 300000L, Long.class},
|
||||
{FORMAT_JA_JP_SHORT, "-30\u4E07", -300000L, Long.class},
|
||||
{FORMAT_JA_JP_SHORT, "12345679\u5146", 1.2345679E19, Double.class},
|
||||
{FORMAT_JA_JP_SHORT, "-12345679\u5146", -1.2345679E19, Double.class},
|
||||
{FORMAT_IT_SHORT, "-99", -99L, Long.class},
|
||||
{FORMAT_IT_SHORT, "1\u00a0Mln", 1000000L, Long.class},
|
||||
{FORMAT_IT_SHORT, "30\u00a0Mln", 30000000L, Long.class},
|
||||
{FORMAT_IT_SHORT, "-30\u00a0Mln", -30000000L, Long.class},
|
||||
{FORMAT_IT_SHORT, "12345679\u00a0Bln", 1.2345679E19, Double.class},
|
||||
{FORMAT_IT_SHORT, "-12345679\u00a0Bln", -1.2345679E19, Double.class},
|
||||
{FORMAT_SW_LONG, "-0.0", -0.0, Double.class},
|
||||
{FORMAT_SW_LONG, "499", 499L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 1", 1000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 3", 3000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 17", 17000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu -3", -3000L, Long.class},
|
||||
{FORMAT_SW_LONG, "499", 499L, Long.class},
|
||||
{FORMAT_SW_LONG, "-499", -499L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 1", 1000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 3", 3000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu -3", -3000L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu 17", 17000L, Long.class},
|
||||
{FORMAT_SW_LONG, "trilioni 12345679", 1.2345679E19, Double.class},
|
||||
{FORMAT_SW_LONG, "trilioni -12345679", -1.2345679E19, Double.class},
|
||||
{FORMAT_SW_LONG, "elfu 599.01", 599010L, Long.class},
|
||||
{FORMAT_SW_LONG, "elfu -599.01", -599010L, Long.class},
|
||||
{FORMAT_SE_SHORT, "999", 999L, Long.class},
|
||||
{FORMAT_SE_SHORT, "8\u00a0mn", 8000000L, Long.class},
|
||||
{FORMAT_SE_SHORT, "8\u00a0dt", 8000L, Long.class},
|
||||
{FORMAT_SE_SHORT, "12345679\u00a0bn", 1.2345679E19, Double.class},
|
||||
{FORMAT_SE_SHORT, "12345679,89\u00a0bn", 1.2345679890000001E19, Double.class},
|
||||
{FORMAT_SE_SHORT, "\u2212999", -999L, Long.class},
|
||||
{FORMAT_SE_SHORT, "\u22128\u00a0mn", -8000000L, Long.class},
|
||||
{FORMAT_SE_SHORT, "\u22128\u00a0dt", -8000L, Long.class},
|
||||
{FORMAT_SE_SHORT, "\u221212345679\u00a0bn", -1.2345679E19, Double.class},
|
||||
{FORMAT_SE_SHORT, "\u221212345679,89\u00a0bn", -1.2345679890000001E19, Double.class},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "exceptionParse")
|
||||
Object[][] exceptionParseData() {
|
||||
return new Object[][]{
|
||||
// compact number instance, string to parse, null (no o/p; must throws exception)
|
||||
// no number
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42", null},
|
||||
// Invalid prefix
|
||||
{FORMAT_DZ_LONG, "-\u0F66\u0F9F\u0F7C\u0F44,\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F23", null},
|
||||
// Invalid prefix for en_US
|
||||
{FORMAT_EN_US_SHORT, "K12,347", null},
|
||||
// Invalid prefix for ja_JP
|
||||
{FORMAT_JA_JP_SHORT, "\u4E071", null},
|
||||
// Localized minus sign should be used
|
||||
{FORMAT_SE_SHORT, "-8\u00a0mn", null},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "invalidParse")
|
||||
Object[][] invalidParseData() {
|
||||
return new Object[][]{
|
||||
// compact number instance, string to parse, parsed number
|
||||
// Prefix and suffix do not match
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F21 KM", 1000L},
|
||||
// Exponents are unparseable
|
||||
{FORMAT_EN_US_SHORT, "-1.05E4K", -1.05},
|
||||
// Default instance does not allow grouping
|
||||
{FORMAT_EN_US_SHORT, "12,347", 12L},
|
||||
// Take partial suffix "K" as 1000 for en_US_SHORT patterns
|
||||
{FORMAT_EN_US_SHORT, "12KM", 12000L},
|
||||
// Invalid suffix
|
||||
{FORMAT_HI_IN_LONG, "-1 \u00a0\u0915.", -1L},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "fieldPosition")
|
||||
Object[][] formatFieldPositionData() {
|
||||
return new Object[][]{
|
||||
//compact number instance, number to format, field, start position, end position, formatted string
|
||||
{FORMAT_DZ_LONG, -3500, NumberFormat.Field.SIGN, 0, 1, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F24"},
|
||||
{FORMAT_DZ_LONG, 3500, NumberFormat.Field.INTEGER, 9, 10, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F24"},
|
||||
{FORMAT_DZ_LONG, -3500, NumberFormat.Field.INTEGER, 10, 11, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F24"},
|
||||
{FORMAT_DZ_LONG, 999, NumberFormat.Field.INTEGER, 0, 3, "\u0F29\u0F29\u0F29"},
|
||||
{FORMAT_DZ_LONG, -999, NumberFormat.Field.INTEGER, 1, 4, "-\u0F29\u0F29\u0F29"},
|
||||
{FORMAT_DZ_LONG, 3500, NumberFormat.Field.PREFIX, 0, 9, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F24"},
|
||||
{FORMAT_DZ_LONG, -3500, NumberFormat.Field.PREFIX, 0, 10, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F24"},
|
||||
{FORMAT_DZ_LONG, 999, NumberFormat.Field.PREFIX, 0, 0, "\u0F29\u0F29\u0F29"},
|
||||
{FORMAT_EN_US_SHORT, -3500, NumberFormat.Field.SIGN, 0, 1, "-4K"},
|
||||
{FORMAT_EN_US_SHORT, 3500, NumberFormat.Field.INTEGER, 0, 1, "4K"},
|
||||
{FORMAT_EN_US_SHORT, 14900000067L, NumberFormat.Field.INTEGER, 0, 2, "15B"},
|
||||
{FORMAT_EN_US_SHORT, -1000, NumberFormat.Field.PREFIX, 0, 1, "-1K"},
|
||||
{FORMAT_EN_US_SHORT, 3500, NumberFormat.Field.SUFFIX, 1, 2, "4K"},
|
||||
{FORMAT_EN_US_SHORT, 14900000067L, NumberFormat.Field.SUFFIX, 2, 3, "15B"},
|
||||
{FORMAT_EN_LONG, 3500, NumberFormat.Field.INTEGER, 0, 1, "4 thousand"},
|
||||
{FORMAT_EN_LONG, 14900000067L, NumberFormat.Field.INTEGER, 0, 2, "15 billion"},
|
||||
{FORMAT_EN_LONG, 3500, NumberFormat.Field.SUFFIX, 1, 10, "4 thousand"},
|
||||
{FORMAT_EN_LONG, 14900000067L, NumberFormat.Field.SUFFIX, 2, 10, "15 billion"},
|
||||
{FORMAT_JA_JP_SHORT, 14900000067L, NumberFormat.Field.INTEGER, 0, 3, "149\u5104"},
|
||||
{FORMAT_JA_JP_SHORT, -999.99, NumberFormat.Field.INTEGER, 1, 6, "-1,000"},
|
||||
{FORMAT_JA_JP_SHORT, 14900000067L, NumberFormat.Field.SUFFIX, 3, 4, "149\u5104"},
|
||||
{FORMAT_JA_JP_SHORT, -999.99, NumberFormat.Field.SUFFIX, 0, 0, "-1,000"},
|
||||
{FORMAT_JA_JP_SHORT, -999.99, NumberFormat.Field.SIGN, 0, 1, "-1,000"},
|
||||
{FORMAT_HI_IN_LONG, -14900000067L, NumberFormat.Field.SIGN, 0, 1,
|
||||
"-15 \u0905\u0930\u092C"},
|
||||
{FORMAT_HI_IN_LONG, 3500, NumberFormat.Field.INTEGER, 0, 1,
|
||||
"4 \u0939\u091C\u093C\u093E\u0930"},
|
||||
{FORMAT_HI_IN_LONG, 14900000067L, NumberFormat.Field.INTEGER, 0, 2,
|
||||
"15 \u0905\u0930\u092C"},
|
||||
{FORMAT_HI_IN_LONG, 3500, NumberFormat.Field.SUFFIX, 1, 7,
|
||||
"4 \u0939\u091C\u093C\u093E\u0930"},
|
||||
{FORMAT_HI_IN_LONG, 14900000067L, NumberFormat.Field.SUFFIX, 2, 6,
|
||||
"15 \u0905\u0930\u092C"},
|
||||
{FORMAT_SE_SHORT, 8000000L, NumberFormat.Field.SUFFIX, 1, 4, "8\u00a0mn"},
|
||||
{FORMAT_SE_SHORT, 8000.98, NumberFormat.Field.SUFFIX, 1, 4, "8\u00a0dt"},
|
||||
{FORMAT_SE_SHORT, new BigInteger("12345678901234567890"), NumberFormat.Field.SUFFIX, 8, 11, "12345679\u00a0bn"},
|
||||
{FORMAT_SE_SHORT, new BigDecimal("12345678901234567890.98"), NumberFormat.Field.SUFFIX, 8, 11, "12345679\u00a0bn"},
|
||||
{FORMAT_SE_SHORT, -8000000L, NumberFormat.Field.INTEGER, 1, 2, "\u22128\u00a0mn"},
|
||||
{FORMAT_SE_SHORT, -8000.98, NumberFormat.Field.SIGN, 0, 1, "\u22128\u00a0dt"},
|
||||
{FORMAT_SE_SHORT, new BigDecimal("-48982865901234567890.98"), NumberFormat.Field.INTEGER, 1, 9, "\u221248982866\u00a0bn"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "varParsePosition")
|
||||
Object[][] varParsePosition() {
|
||||
return new Object[][]{
|
||||
// compact number instance, parse string, parsed number,
|
||||
// start position, end position, error index
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F21 KM", 1000L, 0, 10, -1},
|
||||
// Invalid prefix returns null
|
||||
{FORMAT_DZ_LONG, "Number is: -\u0F66\u0F9F\u0F7C\u0F44,\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F23", null, 11, 11, 11},
|
||||
// Returns null
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42", null, 0, 0, 0},
|
||||
{FORMAT_EN_US_SHORT, "Exponent: -1.05E4K", -1.05, 10, 15, -1},
|
||||
// Default instance does not allow grouping
|
||||
{FORMAT_EN_US_SHORT, "12,347", 12L, 0, 2, -1},
|
||||
// Invalid suffix "KM" for en_US_SHORT patterns
|
||||
{FORMAT_EN_US_SHORT, "12KM", 12000L, 0, 3, -1},
|
||||
// Invalid suffix
|
||||
{FORMAT_HI_IN_LONG, "-1 \u00a0\u0915.", -1L, 0, 2, -1},
|
||||
{FORMAT_EN_LONG, "Number is: 12345679 trillion",
|
||||
1.2345679E19, 11, 28, -1},
|
||||
{FORMAT_EN_LONG, "Number is: -12345679 trillion",
|
||||
-1.2345679E19, 11, 29, -1},
|
||||
{FORMAT_EN_LONG, "parse 12 thousand and four", 12000L, 6, 17, -1},};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstanceCreation() {
|
||||
Stream.of(NumberFormat.getAvailableLocales()).forEach(l -> NumberFormat
|
||||
.getCompactNumberInstance(l, NumberFormat.Style.SHORT).format(10000));
|
||||
Stream.of(NumberFormat.getAvailableLocales()).forEach(l -> NumberFormat
|
||||
.getCompactNumberInstance(l, NumberFormat.Style.LONG).format(10000));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "format")
|
||||
public void testFormat(NumberFormat cnf, Object number,
|
||||
String expected) {
|
||||
CompactFormatAndParseHelper.testFormat(cnf, number, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parse")
|
||||
public void testParse(NumberFormat cnf, String parseString,
|
||||
Number expected, Class<? extends Number> returnType) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, returnType);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parse")
|
||||
public void testParsePosition(NumberFormat cnf, String parseString,
|
||||
Number expected, Class<? extends Number> returnType) throws ParseException {
|
||||
ParsePosition pos = new ParsePosition(0);
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, pos, returnType);
|
||||
assertEquals(pos.getIndex(), parseString.length());
|
||||
assertEquals(pos.getErrorIndex(), -1);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "varParsePosition")
|
||||
public void testVarParsePosition(NumberFormat cnf, String parseString,
|
||||
Number expected, int startPosition, int indexPosition,
|
||||
int errPosition) throws ParseException {
|
||||
ParsePosition pos = new ParsePosition(startPosition);
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, pos, null);
|
||||
assertEquals(pos.getIndex(), indexPosition);
|
||||
assertEquals(pos.getErrorIndex(), errPosition);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "exceptionParse", expectedExceptions = ParseException.class)
|
||||
public void throwsParseException(NumberFormat cnf, String parseString,
|
||||
Number expected) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, null);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidParse")
|
||||
public void testInvalidParse(NumberFormat cnf, String parseString,
|
||||
Number expected) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, null);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fieldPosition")
|
||||
public void testFormatWithFieldPosition(NumberFormat nf,
|
||||
Object number, Format.Field field, int posStartExpected,
|
||||
int posEndExpected, String expected) {
|
||||
FieldPosition pos = new FieldPosition(field);
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuffer result = nf.format(number, buf, pos);
|
||||
assertEquals(result.toString(), expected, "Incorrect formatting of the number '"
|
||||
+ number + "'");
|
||||
assertEquals(pos.getBeginIndex(), posStartExpected, "Incorrect start position"
|
||||
+ " while formatting the number '" + number + "', for the field " + field);
|
||||
assertEquals(pos.getEndIndex(), posEndExpected, "Incorrect end position"
|
||||
+ " while formatting the number '" + number + "', for the field " + field);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the validity of compact number patterns specified through
|
||||
* CompactNumberFormat constructor
|
||||
* @run testng/othervm TestCompactPatternsValidity
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestCompactPatternsValidity {
|
||||
|
||||
// Max range 10^4
|
||||
private static final String[] COMPACT_PATTERN1 = new String[]{"0", "0", "0", "0K", "00K"};
|
||||
// Quoted special character '.' as prefix
|
||||
private static final String[] COMPACT_PATTERN2 = new String[]{"0", "'.'K0"};
|
||||
// Quoted special character '.' as suffix
|
||||
private static final String[] COMPACT_PATTERN3 = new String[]{"0", "0", "0", "0K", "00K'.'"};
|
||||
// Containing both prefix and suffix
|
||||
private static final String[] COMPACT_PATTERN4 = new String[]{"", "", "H0H", "0K", "00K", "H0G"};
|
||||
// Differing while specifying prefix and suffix
|
||||
private static final String[] COMPACT_PATTERN5 = new String[]{"", "", "", "0K", "K0"};
|
||||
// Containing both prefix ('.') and suffix (K)
|
||||
private static final String[] COMPACT_PATTERN6 = new String[]{"0", "", "", "'.'0K"};
|
||||
// Quoted special character ',' as suffix
|
||||
private static final String[] COMPACT_PATTERN7 = new String[]{"", "0", "0", "0K','"};
|
||||
// Most commonly used type of compact patterns with 15 elements
|
||||
private static final String[] COMPACT_PATTERN8 = new String[]{"", "", "", "0K", "00K", "000K", "0M",
|
||||
"00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"};
|
||||
// All empty or special patterns; checking the default formatting behaviour
|
||||
private static final String[] COMPACT_PATTERN9 = new String[]{"", "", "", "0", "0", "", "", "", "", "", "", "", "", "", ""};
|
||||
// Patterns beyond 10^19; divisors beyond long range
|
||||
private static final String[] COMPACT_PATTERN10 = new String[]{"", "", "", "0K", "00K", "000K", "0M", "00M",
|
||||
"000M", "0B", "00B", "000B", "0T", "00T", "000T", "0L", "00L", "000L", "0XL", "00XL"};
|
||||
// Containing positive;negative subpatterns
|
||||
private static final String[] COMPACT_PATTERN11 = new String[]{"", "", "", "elfu 0;elfu -0", "elfu 00;elfu -00",
|
||||
"elfu 000;elfu -000", "milioni 0;milioni -0", "milioni 00;milioni -00", "milioni 000;milioni -000"};
|
||||
// Containing both prefix and suffix and positive;negative subpatern
|
||||
private static final String[] COMPACT_PATTERN12 = new String[]{"", "", "H0H;H-0H", "0K;0K-", "00K;-00K", "H0G;-H0G"};
|
||||
|
||||
@DataProvider(name = "invalidPatterns")
|
||||
Object[][] invalidCompactPatterns() {
|
||||
return new Object[][]{
|
||||
// compact patterns
|
||||
// Pattern containing unquoted special character '.'
|
||||
{new String[]{"", "", "", "0K", "00K."}},
|
||||
// Pattern containing invalid single quote
|
||||
{new String[]{"", "", "", "0 'do", "00K"}},
|
||||
{new String[]{"", "", "", "0K", "00 don't"}},
|
||||
// A non empty pattern containing no 0s (min integer digits)
|
||||
{new String[]{"K", "0K", "00K"}},
|
||||
// 0s (min integer digits) exceeding for the range at index 3
|
||||
{new String[]{"", "", "0K", "00000K"}},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "validPatternsFormat")
|
||||
Object[][] validPatternsFormat() {
|
||||
return new Object[][]{
|
||||
// compact patterns, numbers, expected output
|
||||
{COMPACT_PATTERN1, List.of(200, 1000, 3000, 500000), List.of("200", "1K", "3K", "500K")},
|
||||
{COMPACT_PATTERN2, List.of(1, 20, 3000), List.of("1", ".K2", ".K300")},
|
||||
{COMPACT_PATTERN3, List.of(100.99, 1000, 30000), List.of("101", "1K", "30K.")},
|
||||
{COMPACT_PATTERN4, List.of(0.0, 500, -500, 30000, 5000000), List.of("0", "H5H", "-H5H", "30K", "H50G")},
|
||||
{COMPACT_PATTERN5, List.of(100, 1000, 30000), List.of("100", "1K", "K3")},
|
||||
{COMPACT_PATTERN6, List.of(20.99, 1000, 30000), List.of("21", ".1K", ".30K")},
|
||||
{COMPACT_PATTERN7, List.of(100, 1000, new BigInteger("12345678987654321")), List.of("100", "1K,", "12345678987654K,")},
|
||||
{COMPACT_PATTERN8, List.of(new BigInteger("223565686837667632"), new BigDecimal("12322456774334.89766"), 30000, 3456.78),
|
||||
List.of("223566T", "12T", "30K", "3K")},
|
||||
{COMPACT_PATTERN9, List.of(new BigInteger("223566000000000000"), new BigDecimal("12345678987654567"), 30000, 3000),
|
||||
List.of("223,566,000,000,000,000", "12,345,678,987,654,567", "30,000", "3,000")},
|
||||
{COMPACT_PATTERN10, List.of(new BigInteger("100000000000000000"), new BigInteger("10000000000000000000"), new BigDecimal("555555555555555555555.89766"), 30000),
|
||||
List.of("100L", "10XL", "556XL", "30K")},
|
||||
{COMPACT_PATTERN11, List.of(20.99, -20.99, 1000, -1000, 30000, -30000, new BigInteger("12345678987654321"), new BigInteger("-12345678987654321")),
|
||||
List.of("21", "-21", "elfu 1", "elfu -1", "elfu 30", "elfu -30", "milioni 12345678988", "milioni -12345678988")},
|
||||
{COMPACT_PATTERN12, List.of(0, 500, -500, 30000, -3000, 5000000), List.of("0", "H5H", "H-5H", "30K", "3K-", "H50G")},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "validPatternsParse")
|
||||
Object[][] validPatternsParse() {
|
||||
return new Object[][]{
|
||||
// compact patterns, parse string, expected output
|
||||
{COMPACT_PATTERN1, List.of(".56", "200", ".1K", "3K", "500K"), List.of(0.56, 200L, 100L, 3000L, 500000L)},
|
||||
{COMPACT_PATTERN2, List.of("1", ".K2", ".K300"), List.of(1L, 20L, 3000L)},
|
||||
{COMPACT_PATTERN3, List.of("101", "1K", "30K."), List.of(101L, 1000L, 30000L)},
|
||||
{COMPACT_PATTERN4, List.of("0", "H5H", "-H5H", "30K", "H50G"), List.of(0L, 500L, -500L, 30000L, 5000000L)},
|
||||
{COMPACT_PATTERN5, List.of("100", "1K", "K3"), List.of(100L, 1000L, 30000L)},
|
||||
{COMPACT_PATTERN6, List.of("21", ".1K", ".30K"), List.of(21L, 1000L, 30000L)},
|
||||
{COMPACT_PATTERN7, List.of("100", "1K,", "12345678987654K,"), List.of(100L, 1000L, 12345678987654000L)},
|
||||
{COMPACT_PATTERN8, List.of("223566T", "12T", "30K", "3K"), List.of(223566000000000000L, 12000000000000L, 30000L, 3000L)},
|
||||
{COMPACT_PATTERN10, List.of("1L", "100L", "10XL", "556XL", "30K"), List.of(1000000000000000L, 100000000000000000L, 1.0E19, 5.56E20, 30000L)},
|
||||
{COMPACT_PATTERN11, List.of("21", "-21", "100.90", "-100.90", "elfu 1", "elfu -1", "elfu 30", "elfu -30", "milioni 12345678988", "milioni -12345678988"),
|
||||
List.of(21L, -21L, 100.90, -100.90, 1000L, -1000L, 30000L, -30000L, 12345678988000000L, -12345678988000000L)},
|
||||
{COMPACT_PATTERN12, List.of("0", "H5H", "H-5H", "30K", "30K-", "H50G"), List.of(0L, 500L, -500L, 30000L, -30000L, 5000000L)},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidPatterns",
|
||||
expectedExceptions = RuntimeException.class)
|
||||
public void testInvalidCompactPatterns(String[] compactPatterns) {
|
||||
new CompactNumberFormat("#,##0.0#", DecimalFormatSymbols
|
||||
.getInstance(Locale.US), compactPatterns);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validPatternsFormat")
|
||||
public void testValidPatternsFormat(String[] compactPatterns,
|
||||
List<Object> numbers, List<String> expected) {
|
||||
CompactNumberFormat fmt = new CompactNumberFormat("#,##0.0#",
|
||||
DecimalFormatSymbols.getInstance(Locale.US), compactPatterns);
|
||||
for (int index = 0; index < numbers.size(); index++) {
|
||||
CompactFormatAndParseHelper.testFormat(fmt, numbers.get(index),
|
||||
expected.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "validPatternsParse")
|
||||
public void testValidPatternsParse(String[] compactPatterns,
|
||||
List<String> parseString, List<Number> numbers) throws ParseException {
|
||||
CompactNumberFormat fmt = new CompactNumberFormat("#,##0.0#",
|
||||
DecimalFormatSymbols.getInstance(Locale.US), compactPatterns);
|
||||
for (int index = 0; index < parseString.size(); index++) {
|
||||
CompactFormatAndParseHelper.testParse(fmt, parseString.get(index),
|
||||
numbers.get(index), null, null);
|
||||
}
|
||||
}
|
||||
}
|
167
test/jdk/java/text/Format/CompactNumberFormat/TestEquality.java
Normal file
167
test/jdk/java/text/Format/CompactNumberFormat/TestEquality.java
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the equals and hashCode method of CompactNumberFormat
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestEquality
|
||||
*
|
||||
*/
|
||||
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestEquality {
|
||||
|
||||
@Test
|
||||
public void testEquality() {
|
||||
CompactNumberFormat cnf1 = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
CompactNumberFormat cnf2 = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
// A custom compact instance with the same state as
|
||||
// compact number instance of "en_US" locale with SHORT style
|
||||
String decimalPattern = "#,##0.###";
|
||||
String[] compactPatterns = new String[]{"", "", "", "0K", "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"};
|
||||
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
|
||||
CompactNumberFormat cnf3 = new CompactNumberFormat(decimalPattern, symbols, compactPatterns);
|
||||
|
||||
// A compact instance created with different decimalPattern than cnf3
|
||||
CompactNumberFormat cnf4 = new CompactNumberFormat("#,#0.0#", symbols, compactPatterns);
|
||||
|
||||
// A compact instance created with different format symbols than cnf3
|
||||
CompactNumberFormat cnf5 = new CompactNumberFormat(decimalPattern,
|
||||
DecimalFormatSymbols.getInstance(Locale.JAPAN), compactPatterns);
|
||||
|
||||
// A compact instance created with different compact patterns than cnf3
|
||||
CompactNumberFormat cnf6 = new CompactNumberFormat(decimalPattern,
|
||||
symbols, new String[]{"", "", "", "0K", "00K", "000K"});
|
||||
|
||||
// Checking reflexivity
|
||||
if (!cnf1.equals(cnf1)) {
|
||||
throw new RuntimeException("[testEquality() reflexivity FAILED: The compared"
|
||||
+ " objects must be equal]");
|
||||
}
|
||||
|
||||
// Checking symmetry, checking equality of two same objects
|
||||
if (!cnf1.equals(cnf2) || !cnf2.equals(cnf1)) {
|
||||
throw new RuntimeException("[testEquality() symmetry FAILED: The compared"
|
||||
+ " objects must be equal]");
|
||||
}
|
||||
|
||||
// Checking transitivity, three objects must be equal
|
||||
if (!cnf1.equals(cnf2) || !cnf2.equals(cnf3) || !cnf1.equals(cnf3)) {
|
||||
throw new RuntimeException("[testEquality() transitivity FAILED: The compared"
|
||||
+ " objects must be equal]");
|
||||
}
|
||||
|
||||
// Objects must not be equal as the decimalPattern is different
|
||||
checkEquals(cnf3, cnf4, false, "1st", "different decimal pattern");
|
||||
|
||||
// Objects must not be equal as the format symbols instance is different
|
||||
checkEquals(cnf3, cnf5, false, "2nd", "different format symbols");
|
||||
|
||||
// Objects must not be equal as the compact patters are different
|
||||
checkEquals(cnf3, cnf6, false, "3rd", "different compact patterns");
|
||||
|
||||
// Changing the min integer digits of first object; objects must not
|
||||
// be equal
|
||||
cnf1.setMinimumIntegerDigits(5);
|
||||
checkEquals(cnf1, cnf2, false, "4th", "different min integer digits");
|
||||
|
||||
// Changing the min integer digits of second object; objects must
|
||||
// be equal
|
||||
cnf2.setMinimumIntegerDigits(5);
|
||||
checkEquals(cnf1, cnf2, true, "5th", "");
|
||||
|
||||
// Changing the grouping size of first object; objects must not
|
||||
// be equal
|
||||
cnf1.setGroupingSize(4);
|
||||
checkEquals(cnf1, cnf2, false, "6th", "different grouping size");
|
||||
|
||||
// Changing the grouping size if second object; objects must be equal
|
||||
cnf2.setGroupingSize(4);
|
||||
checkEquals(cnf1, cnf2, true, "7th", "");
|
||||
|
||||
// Changing the parseBigDecimal of first object; objects must not
|
||||
// be equal
|
||||
cnf1.setParseBigDecimal(true);
|
||||
checkEquals(cnf1, cnf2, false, "8th", "different parse big decimal");
|
||||
|
||||
}
|
||||
|
||||
private void checkEquals(CompactNumberFormat cnf1, CompactNumberFormat cnf2,
|
||||
boolean mustEqual, String nthComparison, String message) {
|
||||
if (cnf1.equals(cnf2) != mustEqual) {
|
||||
if (mustEqual) {
|
||||
throw new RuntimeException("[testEquality() " + nthComparison
|
||||
+ " comparison FAILED: The compared objects must be equal]");
|
||||
} else {
|
||||
throw new RuntimeException("[testEquality() " + nthComparison
|
||||
+ " comparison FAILED: The compared objects must"
|
||||
+ " not be equal because of " + message + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHashCode() {
|
||||
NumberFormat cnf1 = NumberFormat
|
||||
.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
|
||||
NumberFormat cnf2 = NumberFormat
|
||||
.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
|
||||
|
||||
if (cnf1.hashCode() != cnf2.hashCode()) {
|
||||
throw new RuntimeException("[testHashCode() FAILED: hashCode of the"
|
||||
+ " compared objects must match]");
|
||||
}
|
||||
}
|
||||
|
||||
// Test the property of equals and hashCode i.e. two equal object must
|
||||
// always have the same hashCode
|
||||
@Test
|
||||
public void testEqualsAndHashCode() {
|
||||
NumberFormat cnf1 = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.SHORT);
|
||||
cnf1.setMinimumIntegerDigits(5);
|
||||
NumberFormat cnf2 = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.SHORT);
|
||||
cnf2.setMinimumIntegerDigits(5);
|
||||
if (cnf1.equals(cnf2)) {
|
||||
if (cnf1.hashCode() != cnf2.hashCode()) {
|
||||
throw new RuntimeException("[testEqualsAndHashCode() FAILED: two"
|
||||
+ " equal objects must have same hashCode]");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("[testEqualsAndHashCode() FAILED: The"
|
||||
+ " compared objects must be equal]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the functioning of
|
||||
* CompactNumberFormat.formatToCharacterIterator method
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestFormatToCharacterIterator
|
||||
*/
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.Format;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestFormatToCharacterIterator {
|
||||
|
||||
private static final NumberFormat FORMAT_DZ = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("dz"),
|
||||
NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_EN_US = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US,
|
||||
NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_EN_LONG = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"),
|
||||
NumberFormat.Style.LONG);
|
||||
|
||||
@DataProvider(name = "fieldPositions")
|
||||
Object[][] compactFieldPositionData() {
|
||||
return new Object[][]{
|
||||
// compact format instance, number, resulted string, attributes/fields, attribute positions
|
||||
{FORMAT_DZ, 1000.09, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F21",
|
||||
new Format.Field[]{NumberFormat.Field.PREFIX, NumberFormat.Field.INTEGER}, new int[]{0, 9, 9, 10}},
|
||||
{FORMAT_DZ, -999.99, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F21",
|
||||
new Format.Field[]{NumberFormat.Field.SIGN, NumberFormat.Field.PREFIX, NumberFormat.Field.INTEGER},
|
||||
new int[]{0, 1, 1, 10, 10, 11}},
|
||||
{FORMAT_DZ, -0.0, "-\u0F20", new Format.Field[]{NumberFormat.Field.SIGN, NumberFormat.Field.INTEGER}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_DZ, 3000L, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2\u0F42 \u0F23",
|
||||
new Format.Field[]{NumberFormat.Field.PREFIX, NumberFormat.Field.INTEGER}, new int[]{0, 9, 9, 10}},
|
||||
{FORMAT_DZ, new BigInteger("12345678901234567890"),
|
||||
"\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27",
|
||||
new Format.Field[]{NumberFormat.Field.PREFIX, NumberFormat.Field.INTEGER}, new int[]{0, 14, 14, 20}},
|
||||
{FORMAT_DZ, new BigDecimal("12345678901234567890.89"),
|
||||
"\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21\u0F22\u0F23\u0F24\u0F25\u0F27",
|
||||
new Format.Field[]{NumberFormat.Field.PREFIX, NumberFormat.Field.INTEGER}, new int[]{0, 14, 14, 20}},
|
||||
// Zeros
|
||||
{FORMAT_EN_US, 0, "0", new Format.Field[]{NumberFormat.Field.INTEGER}, new int[]{0, 1}},
|
||||
{FORMAT_EN_US, 0.0, "0", new Format.Field[]{NumberFormat.Field.INTEGER}, new int[]{0, 1}},
|
||||
{FORMAT_EN_US, -0.0, "-0", new Format.Field[]{NumberFormat.Field.SIGN, NumberFormat.Field.INTEGER}, new int[]{0, 1, 1, 2}},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_EN_US, 499, "499", new Format.Field[]{NumberFormat.Field.INTEGER}, new int[]{0, 3}},
|
||||
// Boundary number
|
||||
{FORMAT_EN_US, 1000.0, "1K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
// Long
|
||||
{FORMAT_EN_US, 3000L, "3K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_EN_US, 30000L, "30K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
{FORMAT_EN_US, 300000L, "300K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 4}},
|
||||
{FORMAT_EN_US, 3000000L, "3M",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_EN_US, 30000000L, "30M",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
{FORMAT_EN_US, 300000000L, "300M",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 4}},
|
||||
{FORMAT_EN_US, 3000000000L, "3B",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_EN_US, 30000000000L, "30B",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
{FORMAT_EN_US, 300000000000L, "300B",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 4}},
|
||||
{FORMAT_EN_US, 3000000000000L, "3T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_EN_US, 30000000000000L, "30T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
{FORMAT_EN_US, 300000000000000L, "300T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 4}},
|
||||
{FORMAT_EN_US, 3000000000000000L, "3000T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 4, 4, 5}},
|
||||
// Double
|
||||
{FORMAT_EN_US, 3000.0, "3K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 2}},
|
||||
{FORMAT_EN_US, 30000.0, "30K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
{FORMAT_EN_US, 300000.0, "300K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 4}},
|
||||
{FORMAT_EN_US, 3000000000000000.0, "3000T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 4, 4, 5}},
|
||||
// BigInteger
|
||||
{FORMAT_EN_US, new BigInteger("12345678901234567890"), "12345679T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 8, 8, 9}},
|
||||
// BigDecimal
|
||||
{FORMAT_EN_US, new BigDecimal("12345678901234567890.89"), "12345679T",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 8, 8, 9}},
|
||||
// Number as exponent
|
||||
{FORMAT_EN_US, 9.78313E+3, "10K",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 3}},
|
||||
// Less than 1000 no suffix
|
||||
{FORMAT_EN_LONG, 999, "999", new Format.Field[]{NumberFormat.Field.INTEGER}, new int[]{0, 3}},
|
||||
// Round the value and then format
|
||||
{FORMAT_EN_LONG, 999.99, "1 thousand",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 10}},
|
||||
// 10 thousand
|
||||
{FORMAT_EN_LONG, 99000, "99 thousand",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 2, 2, 11}},
|
||||
// Long path
|
||||
{FORMAT_EN_LONG, 330000, "330 thousand",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 3, 3, 12}},
|
||||
// Double path
|
||||
{FORMAT_EN_LONG, 3000.90, "3 thousand",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 1, 1, 10}},
|
||||
// BigInteger path
|
||||
{FORMAT_EN_LONG, new BigInteger("12345678901234567890"), "12345679 trillion",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 8, 8, 17}},
|
||||
// BigDecimal path
|
||||
{FORMAT_EN_LONG, new BigDecimal("12345678901234567890.89"), "12345679 trillion",
|
||||
new Format.Field[]{NumberFormat.Field.INTEGER, NumberFormat.Field.SUFFIX}, new int[]{0, 8, 8, 17}}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "fieldPositions")
|
||||
public void testFormatToCharacterIterator(NumberFormat fmt, Object number,
|
||||
String expected, Format.Field[] expectedFields, int[] positions) {
|
||||
AttributedCharacterIterator iterator = fmt.formatToCharacterIterator(number);
|
||||
assertEquals(getText(iterator), expected, "Incorrect formatting of the number '"
|
||||
+ number + "'");
|
||||
|
||||
iterator.first();
|
||||
// Check start and end index of the formatted string
|
||||
assertEquals(iterator.getBeginIndex(), 0, "Incorrect start index: "
|
||||
+ iterator.getBeginIndex() + " of the formatted string: " + expected);
|
||||
assertEquals(iterator.getEndIndex(), expected.length(), "Incorrect end index: "
|
||||
+ iterator.getEndIndex() + " of the formatted string: " + expected);
|
||||
|
||||
// Check the attributes returned by the formatToCharacterIterator
|
||||
assertEquals(iterator.getAllAttributeKeys(), Set.of(expectedFields),
|
||||
"Attributes do not match while formatting number: " + number);
|
||||
|
||||
// Check the begin and end index for attributes
|
||||
iterator.first();
|
||||
int currentPosition = 0;
|
||||
do {
|
||||
int start = iterator.getRunStart();
|
||||
int end = iterator.getRunLimit();
|
||||
assertEquals(start, positions[currentPosition],
|
||||
"Incorrect start position for the attribute(s): "
|
||||
+ iterator.getAttributes().keySet());
|
||||
assertEquals(end, positions[currentPosition + 1],
|
||||
"Incorrect end position for the attribute(s): "
|
||||
+ iterator.getAttributes().keySet());
|
||||
currentPosition = currentPosition + 2;
|
||||
iterator.setIndex(end);
|
||||
} while (iterator.current() != CharacterIterator.DONE);
|
||||
}
|
||||
|
||||
// Create the formatted string from returned AttributedCharacterIterator
|
||||
private String getText(AttributedCharacterIterator iterator) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (char c = iterator.first(); c != CharacterIterator.DONE;
|
||||
c = iterator.next()) {
|
||||
buffer.append(c);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the functioning of compact number format by changing the
|
||||
* formatting parameters. For example, min fraction digits, grouping
|
||||
* size etc.
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestMutatingInstance
|
||||
*/
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestMutatingInstance {
|
||||
|
||||
private static final NumberFormat FORMAT_FRACTION = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_GROUPING = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_MININTEGER = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final NumberFormat FORMAT_PARSEINTONLY = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
// No compact patterns are specified for this instance except at index 4.
|
||||
// This is to test how the behaviour differs between compact number formatting
|
||||
// and general number formatting
|
||||
private static final NumberFormat FORMAT_NO_PATTERNS = new CompactNumberFormat(
|
||||
"#,##0.0#", DecimalFormatSymbols.getInstance(Locale.US),
|
||||
new String[]{"", "", "", "", "00K", "", "", "", "", "", "", "", "", "", ""});
|
||||
|
||||
@BeforeTest
|
||||
public void mutateInstances() {
|
||||
FORMAT_FRACTION.setMinimumFractionDigits(2);
|
||||
FORMAT_GROUPING.setGroupingSize(3);
|
||||
FORMAT_GROUPING.setGroupingUsed(true);
|
||||
FORMAT_MININTEGER.setMinimumIntegerDigits(5);
|
||||
FORMAT_PARSEINTONLY.setParseIntegerOnly(true);
|
||||
FORMAT_PARSEINTONLY.setGroupingUsed(true);
|
||||
// Setting min fraction digits and other fields does not effect
|
||||
// the general number formatting behaviour, when no compact number
|
||||
// patterns are specified
|
||||
FORMAT_NO_PATTERNS.setMinimumFractionDigits(2);
|
||||
}
|
||||
|
||||
@DataProvider(name = "format")
|
||||
Object[][] compactFormatData() {
|
||||
return new Object[][]{
|
||||
{FORMAT_FRACTION, 1900, "1.90 thousand"},
|
||||
{FORMAT_FRACTION, 1000, "1.00 thousand"},
|
||||
{FORMAT_FRACTION, 9090.99, "9.09 thousand"},
|
||||
{FORMAT_FRACTION, new BigDecimal(12346567890987654.32),
|
||||
"12346.57 trillion"},
|
||||
{FORMAT_FRACTION, new BigInteger("12346567890987654"),
|
||||
"12346.57 trillion"},
|
||||
{FORMAT_GROUPING, new BigDecimal(12346567890987654.32),
|
||||
"12,347 trillion"},
|
||||
{FORMAT_GROUPING, 100000, "100 thousand"},
|
||||
{FORMAT_MININTEGER, 10000, "00010 thousand"},
|
||||
{FORMAT_NO_PATTERNS, 100000, "100,000"},
|
||||
{FORMAT_NO_PATTERNS, 1000.998, "1,001"},
|
||||
{FORMAT_NO_PATTERNS, 10900, "10.90K"},
|
||||
{FORMAT_NO_PATTERNS, new BigDecimal(12346567890987654.32), "12,346,567,890,987,654"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "parse")
|
||||
Object[][] compactParseData() {
|
||||
return new Object[][]{
|
||||
{FORMAT_FRACTION, "190 thousand", 190000L},
|
||||
{FORMAT_FRACTION, "19.9 thousand", 19900L},
|
||||
{FORMAT_GROUPING, "12,346 thousand", 12346000L},
|
||||
{FORMAT_PARSEINTONLY, "12345 thousand", 12345000L},
|
||||
{FORMAT_PARSEINTONLY, "12,345 thousand", 12345000L},
|
||||
{FORMAT_PARSEINTONLY, "12.345 thousand", 12000L},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "format")
|
||||
public void formatCompactNumber(NumberFormat nf,
|
||||
Object number, String expected) {
|
||||
CompactFormatAndParseHelper.testFormat(nf, number, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parse")
|
||||
public void parseCompactNumber(NumberFormat nf,
|
||||
String parseString, Number expected) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(nf, parseString, expected, null, null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks CNF.parse() when parseBigDecimal is set to true
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestParseBigDecimal
|
||||
*/
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class TestParseBigDecimal {
|
||||
|
||||
private static final CompactNumberFormat FORMAT_DZ_LONG = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("dz"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_EN_US_SHORT = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_EN_LONG = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("en"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_HI_IN_LONG = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_JA_JP_SHORT = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_IT_SHORT = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("it"), NumberFormat.Style.SHORT);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_SW_LONG = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("sw"), NumberFormat.Style.LONG);
|
||||
|
||||
private static final CompactNumberFormat FORMAT_SE_SHORT = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(new Locale("se"), NumberFormat.Style.SHORT);
|
||||
|
||||
@BeforeTest
|
||||
public void mutateInstances() {
|
||||
FORMAT_DZ_LONG.setParseBigDecimal(true);
|
||||
FORMAT_EN_US_SHORT.setParseBigDecimal(true);
|
||||
FORMAT_EN_LONG.setParseBigDecimal(true);
|
||||
FORMAT_HI_IN_LONG.setParseBigDecimal(true);
|
||||
FORMAT_JA_JP_SHORT.setParseBigDecimal(true);
|
||||
FORMAT_IT_SHORT.setParseBigDecimal(true);
|
||||
FORMAT_SW_LONG.setParseBigDecimal(true);
|
||||
FORMAT_SE_SHORT.setParseBigDecimal(true);
|
||||
}
|
||||
|
||||
@DataProvider(name = "parse")
|
||||
Object[][] compactParseData() {
|
||||
return new Object[][]{
|
||||
// compact number format instance, string to parse, parsed number
|
||||
{FORMAT_DZ_LONG, "\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F21", new BigDecimal("1000")},
|
||||
{FORMAT_DZ_LONG, "-\u0F66\u0F9F\u0F7C\u0F44\u0F0B\u0F55\u0FB2"
|
||||
+ "\u0F42 \u0F23", new BigDecimal("-3000")},
|
||||
{FORMAT_DZ_LONG, "\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62"
|
||||
+ "\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21"
|
||||
+ "\u0F22\u0F23\u0F24\u0F25\u0F27", new BigDecimal("12345700000000000000")},
|
||||
{FORMAT_DZ_LONG, "-\u0F51\u0F74\u0F44\u0F0B\u0F55\u0FB1\u0F74\u0F62"
|
||||
+ "\u0F0B\u0F66\u0F0B\u0F61\u0F0B \u0F21"
|
||||
+ "\u0F22\u0F23\u0F24\u0F25\u0F27", new BigDecimal("-12345700000000000000")},
|
||||
{FORMAT_EN_US_SHORT, "-0.0", new BigDecimal("-0.0")},
|
||||
{FORMAT_EN_US_SHORT, "0", new BigDecimal("0")},
|
||||
{FORMAT_EN_US_SHORT, "499", new BigDecimal("499")},
|
||||
{FORMAT_EN_US_SHORT, "-499", new BigDecimal("-499")},
|
||||
{FORMAT_EN_US_SHORT, "499.89", new BigDecimal("499.89")},
|
||||
{FORMAT_EN_US_SHORT, "-499.89", new BigDecimal("-499.89")},
|
||||
{FORMAT_EN_US_SHORT, "1K", new BigDecimal("1000")},
|
||||
{FORMAT_EN_US_SHORT, "-1K", new BigDecimal("-1000")},
|
||||
{FORMAT_EN_US_SHORT, "3K", new BigDecimal("3000")},
|
||||
{FORMAT_EN_US_SHORT, "-3K", new BigDecimal("-3000")},
|
||||
{FORMAT_EN_US_SHORT, "17K", new BigDecimal("17000")},
|
||||
{FORMAT_EN_US_SHORT, "-17K", new BigDecimal("-17000")},
|
||||
{FORMAT_EN_US_SHORT, "12345678901234567890",
|
||||
new BigDecimal("12345678901234567890")},
|
||||
{FORMAT_EN_US_SHORT, "12345679T", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_EN_US_SHORT, "-12345679T", new BigDecimal("-12345679000000000000")},
|
||||
{FORMAT_EN_US_SHORT, "599.01K", new BigDecimal("599010.00")},
|
||||
{FORMAT_EN_US_SHORT, "-599.01K", new BigDecimal("-599010.00")},
|
||||
{FORMAT_EN_US_SHORT, "599444444.90T", new BigDecimal("599444444900000000000.00")},
|
||||
{FORMAT_EN_US_SHORT, "-599444444.90T", new BigDecimal("-599444444900000000000.00")},
|
||||
{FORMAT_EN_US_SHORT, "123456789012345.5678K",
|
||||
new BigDecimal("123456789012345567.8000")},
|
||||
{FORMAT_EN_US_SHORT, "17.000K", new BigDecimal("17000.000")},
|
||||
{FORMAT_EN_US_SHORT, "123.56678K", new BigDecimal("123566.78000")},
|
||||
{FORMAT_EN_US_SHORT, "-123.56678K", new BigDecimal("-123566.78000")},
|
||||
{FORMAT_EN_LONG, "999", new BigDecimal("999")},
|
||||
{FORMAT_EN_LONG, "1 thousand", new BigDecimal("1000")},
|
||||
{FORMAT_EN_LONG, "3 thousand", new BigDecimal("3000")},
|
||||
{FORMAT_EN_LONG, "12345679 trillion", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_HI_IN_LONG, "999", new BigDecimal("999")},
|
||||
{FORMAT_HI_IN_LONG, "-999", new BigDecimal("-999")},
|
||||
{FORMAT_HI_IN_LONG, "1 \u0939\u091C\u093C\u093E\u0930", new BigDecimal("1000")},
|
||||
{FORMAT_HI_IN_LONG, "-1 \u0939\u091C\u093C\u093E\u0930", new BigDecimal("-1000")},
|
||||
{FORMAT_HI_IN_LONG, "3 \u0939\u091C\u093C\u093E\u0930", new BigDecimal("3000")},
|
||||
{FORMAT_HI_IN_LONG, "12345679 \u0916\u0930\u092C", new BigDecimal("1234567900000000000")},
|
||||
{FORMAT_HI_IN_LONG, "-12345679 \u0916\u0930\u092C", new BigDecimal("-1234567900000000000")},
|
||||
{FORMAT_JA_JP_SHORT, "-99", new BigDecimal("-99")},
|
||||
{FORMAT_JA_JP_SHORT, "1\u4E07", new BigDecimal("10000")},
|
||||
{FORMAT_JA_JP_SHORT, "30\u4E07", new BigDecimal("300000")},
|
||||
{FORMAT_JA_JP_SHORT, "-30\u4E07", new BigDecimal("-300000")},
|
||||
{FORMAT_JA_JP_SHORT, "12345679\u5146", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_JA_JP_SHORT, "-12345679\u5146", new BigDecimal("-12345679000000000000")},
|
||||
{FORMAT_IT_SHORT, "-99", new BigDecimal("-99")},
|
||||
{FORMAT_IT_SHORT, "1\u00a0Mln", new BigDecimal("1000000")},
|
||||
{FORMAT_IT_SHORT, "30\u00a0Mln", new BigDecimal("30000000")},
|
||||
{FORMAT_IT_SHORT, "-30\u00a0Mln", new BigDecimal("-30000000")},
|
||||
{FORMAT_IT_SHORT, "12345679\u00a0Bln", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_IT_SHORT, "-12345679\u00a0Bln", new BigDecimal("-12345679000000000000")},
|
||||
{FORMAT_SW_LONG, "-0.0", new BigDecimal("-0.0")},
|
||||
{FORMAT_SW_LONG, "499", new BigDecimal("499")},
|
||||
{FORMAT_SW_LONG, "elfu 1", new BigDecimal("1000")},
|
||||
{FORMAT_SW_LONG, "elfu 3", new BigDecimal("3000")},
|
||||
{FORMAT_SW_LONG, "elfu 17", new BigDecimal("17000")},
|
||||
{FORMAT_SW_LONG, "elfu -3", new BigDecimal("-3000")},
|
||||
{FORMAT_SW_LONG, "-499", new BigDecimal("-499")},
|
||||
{FORMAT_SW_LONG, "elfu 1", new BigDecimal("1000")},
|
||||
{FORMAT_SW_LONG, "elfu 3", new BigDecimal("3000")},
|
||||
{FORMAT_SW_LONG, "elfu -3", new BigDecimal("-3000")},
|
||||
{FORMAT_SW_LONG, "elfu 17", new BigDecimal("17000")},
|
||||
{FORMAT_SW_LONG, "trilioni 12345679", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_SW_LONG, "trilioni -12345679", new BigDecimal("-12345679000000000000")},
|
||||
{FORMAT_SW_LONG, "elfu 599.01", new BigDecimal("599010.00")},
|
||||
{FORMAT_SW_LONG, "elfu -599.01", new BigDecimal("-599010.00")},
|
||||
{FORMAT_SE_SHORT, "999", new BigDecimal("999")},
|
||||
{FORMAT_SE_SHORT, "8\u00a0mn", new BigDecimal("8000000")},
|
||||
{FORMAT_SE_SHORT, "8\u00a0dt", new BigDecimal("8000")},
|
||||
{FORMAT_SE_SHORT, "12345679\u00a0bn", new BigDecimal("12345679000000000000")},
|
||||
{FORMAT_SE_SHORT, "12345679,89\u00a0bn", new BigDecimal("12345679890000000000.00")},
|
||||
{FORMAT_SE_SHORT, "\u2212999", new BigDecimal("-999")},
|
||||
{FORMAT_SE_SHORT, "\u22128\u00a0mn", new BigDecimal("-8000000")},
|
||||
{FORMAT_SE_SHORT, "\u22128\u00a0dt", new BigDecimal("-8000")},
|
||||
{FORMAT_SE_SHORT, "\u221212345679\u00a0bn", new BigDecimal("-12345679000000000000")},
|
||||
{FORMAT_SE_SHORT, "\u221212345679,89\u00a0bn", new BigDecimal("-12345679890000000000.00")},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parse")
|
||||
public void testParse(NumberFormat cnf, String parseString,
|
||||
Number expected) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, BigDecimal.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the formatting and parsing of special values
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestSpecialValues
|
||||
*/
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestSpecialValues {
|
||||
|
||||
private static final NumberFormat FORMAT = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
@DataProvider(name = "formatSpecialValues")
|
||||
Object[][] formatSpecialValues() {
|
||||
return new Object[][]{
|
||||
// number , formatted ouput
|
||||
{+0.0, "0"},
|
||||
{-0.0, "-0"},
|
||||
{Double.MIN_VALUE, "0"},
|
||||
{Double.MIN_NORMAL, "0"},
|
||||
{Double.NaN, "NaN"},
|
||||
{Double.POSITIVE_INFINITY, "\u221E"},
|
||||
{Double.NEGATIVE_INFINITY, "-\u221E"},
|
||||
{Long.MIN_VALUE, "-9223372T"},
|
||||
{Long.MAX_VALUE, "9223372T"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "parseSpecialValues")
|
||||
Object[][] parseSpecialValues() {
|
||||
return new Object[][]{
|
||||
// parse string, parsed number
|
||||
{"-0.0", -0.0},
|
||||
{"" + Long.MIN_VALUE, Long.MIN_VALUE},
|
||||
{"" + Long.MAX_VALUE, Long.MAX_VALUE},
|
||||
{"NaN", Double.NaN},
|
||||
{"\u221E", Double.POSITIVE_INFINITY},
|
||||
{"-\u221E", Double.NEGATIVE_INFINITY},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "formatSpecialValues")
|
||||
public void testFormatSpecialValues(Object number, String expected) {
|
||||
CompactFormatAndParseHelper.testFormat(FORMAT, number, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parseSpecialValues")
|
||||
public void testParseSpecialValues(String parseString, Number expected)
|
||||
throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(FORMAT, parseString, expected, null, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the behaviour of Unicode BCP 47 U Extension with
|
||||
* compact number format
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm TestUExtensionOverride
|
||||
*/
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestUExtensionOverride {
|
||||
|
||||
@DataProvider(name = "compactFormatData")
|
||||
Object[][] compactFormatData() {
|
||||
return new Object[][]{
|
||||
// locale, number, formatted string
|
||||
|
||||
// -nu
|
||||
{Locale.forLanguageTag("en-US-u-nu-deva"), 12345, "\u0967\u0968K"},
|
||||
{Locale.forLanguageTag("en-US-u-nu-sinh"), 12345, "\u0de7\u0de8K"},
|
||||
{Locale.forLanguageTag("en-US-u-nu-zzzz"), 12345, "12K"},
|
||||
// -rg
|
||||
{Locale.forLanguageTag("fr-FR-u-rg-cazzzz"), 1234567,
|
||||
"1\u00a0234\u00a0567"},
|
||||
{Locale.forLanguageTag("fr-FR-u-rg-cazzzz"), 1234567890,
|
||||
"1\u00a0G"},
|
||||
// -nu and -rg
|
||||
{Locale.forLanguageTag("en-US-u-nu-deva-rg-dezzzz"), 12345,
|
||||
"\u0967\u0968K"},
|
||||
{Locale.forLanguageTag("fr-FR-u-nu-zzzz-rg-cazzzz"), 1234567890,
|
||||
"1\u00a0Md"},
|
||||
{Locale.forLanguageTag("fr-FR-u-nu-zzzz-rg-zzzz"), 12345,
|
||||
"12\u00a0k"},
|
||||
{Locale.forLanguageTag("fr-FR-u-rg-cazzzz-nu-deva"), 12345,
|
||||
"\u0967\u0968\u00a0k"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "compactParseData")
|
||||
Object[][] compactParseData() {
|
||||
return new Object[][]{
|
||||
// locale, parse string, parsed number
|
||||
|
||||
// -nu
|
||||
{Locale.forLanguageTag("en-US-u-nu-deva"),
|
||||
"\u0967\u0968K", 12000L},
|
||||
{Locale.forLanguageTag("en-US-u-nu-sinh"),
|
||||
"\u0de7\u0de8K", 12000L},
|
||||
{Locale.forLanguageTag("en-US-u-nu-zzzz"),
|
||||
"12K", 12000L},
|
||||
// -rg
|
||||
{Locale.forLanguageTag("fr-FR-u-rg-cazzzz"),
|
||||
"1\u00a0G", 1000000000L},
|
||||
// -nu and -rg
|
||||
{Locale.forLanguageTag("en-US-u-nu-deva-rg-dezzzz"),
|
||||
"\u0967\u0968K", 12000L},
|
||||
{Locale.forLanguageTag("fr-FR-u-nu-zzzz-rg-cazzzz"),
|
||||
"1\u00a0Md", 1000000000L},
|
||||
{Locale.forLanguageTag("fr-FR-u-nu-zzzz-rg-zzzz"),
|
||||
"12\u00a0k", 12000L},
|
||||
{Locale.forLanguageTag("fr-FR-u-rg-cazzzz-nu-deva"),
|
||||
"\u0967\u0968\u00a0k", 12000L},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "compactFormatData")
|
||||
public void testFormat(Locale locale, double num,
|
||||
String expected) {
|
||||
NumberFormat cnf = NumberFormat.getCompactNumberInstance(locale,
|
||||
NumberFormat.Style.SHORT);
|
||||
CompactFormatAndParseHelper.testFormat(cnf, num, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "compactParseData")
|
||||
public void testParse(Locale locale, String parseString,
|
||||
Number expected) throws ParseException {
|
||||
NumberFormat cnf = NumberFormat.getCompactNumberInstance(locale,
|
||||
NumberFormat.Style.SHORT);
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @summary Checks the compact number format with COMPAT provider. Since the
|
||||
* compact number resources are only provided by CLDR, using COMPAT
|
||||
* as a provider should always use the default patterns added in the
|
||||
* FormatData.java resource bundle
|
||||
* @modules jdk.localedata
|
||||
* @run testng/othervm -Djava.locale.providers=COMPAT TestWithCompatProvider
|
||||
*/
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class TestWithCompatProvider {
|
||||
|
||||
private static final NumberFormat FORMAT_DZ_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(new Locale("dz"), NumberFormat.Style.SHORT);
|
||||
|
||||
private static final NumberFormat FORMAT_EN_US_SHORT = NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
|
||||
|
||||
@DataProvider(name = "format")
|
||||
Object[][] compactFormatData() {
|
||||
return new Object[][]{
|
||||
{FORMAT_DZ_SHORT, 1000.09, "1K"},
|
||||
{FORMAT_DZ_SHORT, -999.99, "-1K"},
|
||||
{FORMAT_DZ_SHORT, -0.0, "-0"},
|
||||
{FORMAT_DZ_SHORT, new BigInteger("12345678901234567890"), "12345679T"},
|
||||
{FORMAT_DZ_SHORT, new BigDecimal("12345678901234567890.89"), "12345679T"},
|
||||
{FORMAT_EN_US_SHORT, -999.99, "-1K"},
|
||||
{FORMAT_EN_US_SHORT, 9999, "10K"},
|
||||
{FORMAT_EN_US_SHORT, 3000.90, "3K"},
|
||||
{FORMAT_EN_US_SHORT, new BigInteger("12345678901234567890"), "12345679T"},
|
||||
{FORMAT_EN_US_SHORT, new BigDecimal("12345678901234567890.89"), "12345679T"},};
|
||||
}
|
||||
|
||||
@DataProvider(name = "parse")
|
||||
Object[][] compactParseData() {
|
||||
return new Object[][]{
|
||||
{FORMAT_DZ_SHORT, "1K", 1000L},
|
||||
{FORMAT_DZ_SHORT, "-3K", -3000L},
|
||||
{FORMAT_DZ_SHORT, "12345700T", 1.23457E19},
|
||||
{FORMAT_EN_US_SHORT, "-99", -99L},
|
||||
{FORMAT_EN_US_SHORT, "10K", 10000L},
|
||||
{FORMAT_EN_US_SHORT, "12345679T", 1.2345679E19},};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "format")
|
||||
public void testFormat(NumberFormat cnf, Object number,
|
||||
String expected) {
|
||||
CompactFormatAndParseHelper.testFormat(cnf, number, expected);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "parse")
|
||||
public void testParse(NumberFormat cnf, String parseString,
|
||||
Number expected) throws ParseException {
|
||||
CompactFormatAndParseHelper.testParse(cnf, parseString, expected, null, null);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @modules jdk.localedata
|
||||
* @summary Checks deserialization of compact number format
|
||||
* @library /java/text/testlib
|
||||
* @build TestDeserializeCNF HexDumpReader
|
||||
* @run testng/othervm TestDeserializeCNF
|
||||
*/
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class TestDeserializeCNF {
|
||||
|
||||
// This object is serialized in cnf1.ser.txt with HALF_UP
|
||||
// rounding mode, groupingsize = 3 and parseBigDecimal = true
|
||||
private static final CompactNumberFormat COMPACT_FORMAT1 = new CompactNumberFormat("#,##0.###",
|
||||
DecimalFormatSymbols.getInstance(Locale.US),
|
||||
new String[]{"", "", "", "0K", "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"});
|
||||
|
||||
// This object is serialized in cnf2.ser.txt with min integer digits = 20
|
||||
// and min fraction digits = 5
|
||||
private static final CompactNumberFormat COMPACT_FORMAT2 = new CompactNumberFormat("#,##0.###",
|
||||
DecimalFormatSymbols.getInstance(Locale.JAPAN),
|
||||
new String[]{"", "", "", "0", "0\u4e07", "00\u4e07", "000\u4e07", "0000\u4e07", "0\u5104", "00\u5104", "000\u5104", "0000\u5104", "0\u5146", "00\u5146", "000\u5146"});
|
||||
|
||||
private static final String FILE_COMPACT_FORMAT1 = "cnf1.ser.txt";
|
||||
private static final String FILE_COMPACT_FORMAT2 = "cnf2.ser.txt";
|
||||
|
||||
@BeforeTest
|
||||
public void mutateInstances() {
|
||||
COMPACT_FORMAT1.setRoundingMode(RoundingMode.HALF_UP);
|
||||
COMPACT_FORMAT1.setGroupingSize(3);
|
||||
COMPACT_FORMAT1.setParseBigDecimal(true);
|
||||
|
||||
COMPACT_FORMAT2.setMinimumIntegerDigits(20);
|
||||
COMPACT_FORMAT2.setMinimumFractionDigits(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserialization() throws IOException, ClassNotFoundException {
|
||||
try (InputStream istream1 = HexDumpReader.getStreamFromHexDump(FILE_COMPACT_FORMAT1);
|
||||
ObjectInputStream ois1 = new ObjectInputStream(istream1);
|
||||
InputStream istream2 = HexDumpReader.getStreamFromHexDump(FILE_COMPACT_FORMAT2);
|
||||
ObjectInputStream ois2 = new ObjectInputStream(istream2);) {
|
||||
|
||||
CompactNumberFormat obj1 = (CompactNumberFormat) ois1.readObject();
|
||||
assertEquals(obj1, COMPACT_FORMAT1, "Deserialized instance is not"
|
||||
+ " equal to the instance serialized in " + FILE_COMPACT_FORMAT1);
|
||||
|
||||
CompactNumberFormat obj2 = (CompactNumberFormat) ois2.readObject();
|
||||
assertEquals(obj2, COMPACT_FORMAT2, "Deserialized instance is not"
|
||||
+ " equal to the instance serialized in " + FILE_COMPACT_FORMAT2);
|
||||
}
|
||||
}
|
||||
|
||||
// The objects are serialized using the serialize() method, the hex
|
||||
// dump printed is copied to respective object files
|
||||
// void serialize(CompactNumberFormat cnf) {
|
||||
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
// try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
// oos.writeObject(cnf);
|
||||
// } catch (IOException ioe) {
|
||||
// throw new RuntimeException(ioe);
|
||||
// }
|
||||
// byte[] ser = baos.toByteArray();
|
||||
// for (byte b : ser) {
|
||||
// System.out.print("" + String.format("%02x", b));
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8177552
|
||||
* @modules jdk.localedata
|
||||
* @summary Checks the serialization feature of CompactNumberFormat
|
||||
* @run testng/othervm TestSerialization
|
||||
*/
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class TestSerialization {
|
||||
|
||||
private static final NumberFormat FORMAT_HI = NumberFormat.getCompactNumberInstance(
|
||||
new Locale("hi"), NumberFormat.Style.SHORT);
|
||||
private static final CompactNumberFormat FORMAT_EN_US = (CompactNumberFormat) NumberFormat
|
||||
.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG);
|
||||
private static final NumberFormat FORMAT_JA_JP = NumberFormat.getCompactNumberInstance(
|
||||
Locale.JAPAN, NumberFormat.Style.SHORT);
|
||||
private static final NumberFormat FORMAT_FR_FR = NumberFormat.getCompactNumberInstance(
|
||||
Locale.FRANCE, NumberFormat.Style.LONG);
|
||||
private static final NumberFormat FORMAT_DE_DE = NumberFormat.getCompactNumberInstance(
|
||||
Locale.GERMANY, NumberFormat.Style.SHORT);
|
||||
private static final NumberFormat FORMAT_KO_KR = NumberFormat.getCompactNumberInstance(
|
||||
Locale.KOREA, NumberFormat.Style.SHORT);
|
||||
|
||||
@BeforeTest
|
||||
public void mutateInstances() {
|
||||
FORMAT_HI.setMinimumFractionDigits(2);
|
||||
FORMAT_HI.setMinimumIntegerDigits(5);
|
||||
|
||||
FORMAT_EN_US.setRoundingMode(RoundingMode.HALF_UP);
|
||||
FORMAT_EN_US.setGroupingSize(3);
|
||||
FORMAT_EN_US.setParseBigDecimal(true);
|
||||
|
||||
FORMAT_JA_JP.setMaximumFractionDigits(30);
|
||||
FORMAT_JA_JP.setMaximumIntegerDigits(30);
|
||||
|
||||
FORMAT_FR_FR.setParseIntegerOnly(true);
|
||||
FORMAT_FR_FR.setGroupingUsed(true);
|
||||
|
||||
// Setting minimum integer digits beyond the allowed range
|
||||
FORMAT_DE_DE.setMinimumIntegerDigits(320);
|
||||
|
||||
// Setting minimum fraction digits beyond the allowed range
|
||||
FORMAT_KO_KR.setMinimumFractionDigits(350);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws IOException, ClassNotFoundException {
|
||||
// Serialize
|
||||
serialize("cdf.ser", FORMAT_HI, FORMAT_EN_US, FORMAT_JA_JP, FORMAT_FR_FR, FORMAT_DE_DE, FORMAT_KO_KR);
|
||||
// Deserialize
|
||||
deserialize("cdf.ser", FORMAT_HI, FORMAT_EN_US, FORMAT_JA_JP, FORMAT_FR_FR, FORMAT_DE_DE, FORMAT_KO_KR);
|
||||
}
|
||||
|
||||
private void serialize(String fileName, NumberFormat... formats)
|
||||
throws IOException {
|
||||
try (ObjectOutputStream os = new ObjectOutputStream(
|
||||
new FileOutputStream(fileName))) {
|
||||
for (NumberFormat fmt : formats) {
|
||||
os.writeObject(fmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void deserialize(String fileName, NumberFormat... formats)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try (ObjectInputStream os = new ObjectInputStream(
|
||||
new FileInputStream(fileName))) {
|
||||
for (NumberFormat fmt : formats) {
|
||||
NumberFormat obj = (NumberFormat) os.readObject();
|
||||
assertEquals(fmt, obj, "Serialized and deserialized"
|
||||
+ " objects do not match");
|
||||
|
||||
long number = 123456789789L;
|
||||
String expected = fmt.format(number);
|
||||
String actual = obj.format(number);
|
||||
assertEquals(actual, expected, "Serialized and deserialized"
|
||||
+ " objects are expected to return same formatted"
|
||||
+ " output for number: " + number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized CompactNumberFormat for TestDeserializeCNF.
|
||||
|
||||
aced00057372001d6a6176612e746578742e436f6d706163744e756d626572466f726d
|
||||
617462ed0c37b8207cf602000642000c67726f7570696e6753697a655a000f70617273
|
||||
65426967446563696d616c5b000f636f6d706163745061747465726e737400135b4c6a
|
||||
6176612f6c616e672f537472696e673b4c000e646563696d616c5061747465726e7400
|
||||
124c6a6176612f6c616e672f537472696e673b4c000c726f756e64696e674d6f646574
|
||||
00184c6a6176612f6d6174682f526f756e64696e674d6f64653b4c000773796d626f6c
|
||||
737400204c6a6176612f746578742f446563696d616c466f726d617453796d626f6c73
|
||||
3b787200166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
|
||||
03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e446967
|
||||
6974734200106d6178496e74656765724469676974734900156d6178696d756d467261
|
||||
6374696f6e4469676974734900146d6178696d756d496e746567657244696769747342
|
||||
00116d696e4672616374696f6e4469676974734200106d696e496e7465676572446967
|
||||
6974734900156d696e696d756d4672616374696f6e4469676974734900146d696e696d
|
||||
756d496e74656765724469676974735a00107061727365496e74656765724f6e6c7949
|
||||
001573657269616c56657273696f6e4f6e53747265616d787200106a6176612e746578
|
||||
742e466f726d6174fbd8bc12e90f1843020000787000007f0000000000000135000100
|
||||
000000000000010000000001780301757200135b4c6a6176612e6c616e672e53747269
|
||||
6e673badd256e7e91d7b4702000078700000000f74000071007e000a71007e000a7400
|
||||
02304b74000330304b7400043030304b740002304d74000330304d7400043030304d74
|
||||
0002304274000330304274000430303042740002305474000330305474000430303054
|
||||
740009232c2323302e2323237e7200166a6176612e6d6174682e526f756e64696e674d
|
||||
6f646500000000000000001200007872000e6a6176612e6c616e672e456e756d000000
|
||||
0000000000120000787074000748414c465f55507372001e6a6176612e746578742e44
|
||||
6563696d616c466f726d617453796d626f6c73501d17990868939c0200114300106465
|
||||
63696d616c536570617261746f72430005646967697443000b6578706f6e656e746961
|
||||
6c43001167726f7570696e67536570617261746f724300096d696e75735369676e4300
|
||||
116d6f6e6574617279536570617261746f724300107061747465726e53657061726174
|
||||
6f724300077065724d696c6c43000770657263656e7449001573657269616c56657273
|
||||
696f6e4f6e53747265616d4300097a65726f44696769744c00034e614e71007e00024c
|
||||
000e63757272656e637953796d626f6c71007e00024c00146578706f6e656e7469616c
|
||||
536570617261746f7271007e00024c0008696e66696e69747971007e00024c0012696e
|
||||
746c43757272656e637953796d626f6c71007e00024c00066c6f63616c657400124c6a
|
||||
6176612f7574696c2f4c6f63616c653b7870002e00230045002c002d002e003b203000
|
||||
250000000300307400034e614e7074000145740003e2889e70737200106a6176612e75
|
||||
74696c2e4c6f63616c657ef811609c30f9ec03000649000868617368636f64654c0007
|
||||
636f756e74727971007e00024c000a657874656e73696f6e7371007e00024c00086c61
|
||||
6e677561676571007e00024c000673637269707471007e00024c000776617269616e74
|
||||
71007e00027870ffffffff740002555371007e000a740002656e71007e000a71007e00
|
||||
0a78
|
@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Hex dump of a serialized CompactNumberFormat for TestDeserializeCNF.
|
||||
|
||||
aced00057372001d6a6176612e746578742e436f6d706163744e756d626572466f726d
|
||||
617462ed0c37b8207cf602000642000c67726f7570696e6753697a655a000f70617273
|
||||
65426967446563696d616c5b000f636f6d706163745061747465726e737400135b4c6a
|
||||
6176612f6c616e672f537472696e673b4c000e646563696d616c5061747465726e7400
|
||||
124c6a6176612f6c616e672f537472696e673b4c000c726f756e64696e674d6f646574
|
||||
00184c6a6176612f6d6174682f526f756e64696e674d6f64653b4c000773796d626f6c
|
||||
737400204c6a6176612f746578742f446563696d616c466f726d617453796d626f6c73
|
||||
3b787200166a6176612e746578742e4e756d626572466f726d6174dff6b3bf137d07e8
|
||||
03000b5a000c67726f7570696e67557365644200116d61784672616374696f6e446967
|
||||
6974734200106d6178496e74656765724469676974734900156d6178696d756d467261
|
||||
6374696f6e4469676974734900146d6178696d756d496e746567657244696769747342
|
||||
00116d696e4672616374696f6e4469676974734200106d696e496e7465676572446967
|
||||
6974734900156d696e696d756d4672616374696f6e4469676974734900146d696e696d
|
||||
756d496e74656765724469676974735a00107061727365496e74656765724f6e6c7949
|
||||
001573657269616c56657273696f6e4f6e53747265616d787200106a6176612e746578
|
||||
742e466f726d6174fbd8bc12e90f1843020000787000057f0000000500000135051400
|
||||
000005000000140000000001780000757200135b4c6a6176612e6c616e672e53747269
|
||||
6e673badd256e7e91d7b4702000078700000000f74000071007e000a71007e000a7400
|
||||
013074000430e4b8877400053030e4b887740006303030e4b88774000730303030e4b8
|
||||
8774000430e584847400053030e58484740006303030e5848474000730303030e58484
|
||||
74000430e585867400053030e58586740006303030e58586740009232c2323302e2323
|
||||
237e7200166a6176612e6d6174682e526f756e64696e674d6f64650000000000000000
|
||||
1200007872000e6a6176612e6c616e672e456e756d0000000000000000120000787074
|
||||
000948414c465f4556454e7372001e6a6176612e746578742e446563696d616c466f72
|
||||
6d617453796d626f6c73501d17990868939c020011430010646563696d616c53657061
|
||||
7261746f72430005646967697443000b6578706f6e656e7469616c43001167726f7570
|
||||
696e67536570617261746f724300096d696e75735369676e4300116d6f6e6574617279
|
||||
536570617261746f724300107061747465726e536570617261746f724300077065724d
|
||||
696c6c43000770657263656e7449001573657269616c56657273696f6e4f6e53747265
|
||||
616d4300097a65726f44696769744c00034e614e71007e00024c000e63757272656e63
|
||||
7953796d626f6c71007e00024c00146578706f6e656e7469616c536570617261746f72
|
||||
71007e00024c0008696e66696e69747971007e00024c0012696e746c43757272656e63
|
||||
7953796d626f6c71007e00024c00066c6f63616c657400124c6a6176612f7574696c2f
|
||||
4c6f63616c653b7870002e00230045002c002d002e003b203000250000000300307400
|
||||
034e614e7074000145740003e2889e70737200106a6176612e7574696c2e4c6f63616c
|
||||
657ef811609c30f9ec03000649000868617368636f64654c0007636f756e7472797100
|
||||
7e00024c000a657874656e73696f6e7371007e00024c00086c616e677561676571007e
|
||||
00024c000673637269707471007e00024c000776617269616e7471007e00027870ffff
|
||||
ffff7400024a5071007e000a7400026a6171007e000a71007e000a78
|
Loading…
Reference in New Issue
Block a user