8227313: Support monetary grouping separator in DecimalFormat/DecimalFormatSymbols
Reviewed-by: joehw
This commit is contained in:
parent
8a1b5ad914
commit
2e237e35fd
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -72,7 +72,9 @@ class Bundle {
|
|||||||
"NumberElements/exponential",
|
"NumberElements/exponential",
|
||||||
"NumberElements/permille",
|
"NumberElements/permille",
|
||||||
"NumberElements/infinity",
|
"NumberElements/infinity",
|
||||||
"NumberElements/nan"
|
"NumberElements/nan",
|
||||||
|
"NumberElements/currencyDecimal",
|
||||||
|
"NumberElements/currencyGroup",
|
||||||
};
|
};
|
||||||
|
|
||||||
private final static String[] TIME_PATTERN_KEYS = {
|
private final static String[] TIME_PATTERN_KEYS = {
|
||||||
@ -810,7 +812,10 @@ class Bundle {
|
|||||||
assert keys == NUMBER_ELEMENT_KEYS;
|
assert keys == NUMBER_ELEMENT_KEYS;
|
||||||
if (key.endsWith("/pattern")) {
|
if (key.endsWith("/pattern")) {
|
||||||
numArray[idx] = "#";
|
numArray[idx] = "#";
|
||||||
} else {
|
} else if (!key.endsWith("currencyDecimal") &&
|
||||||
|
!key.endsWith("currencyGroup")) {
|
||||||
|
// throw error unless it is for "currencyDecimal/Group",
|
||||||
|
// which may be missing.
|
||||||
throw new InternalError("NumberElements: null for " +
|
throw new InternalError("NumberElements: null for " +
|
||||||
key + ", id: " + id);
|
key + ", id: " + id);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -644,19 +644,13 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "decimal":
|
case "decimal":
|
||||||
// for FormatData
|
|
||||||
// copy string for later assembly into NumberElements
|
|
||||||
if (currentContainer.getqName().equals("symbols")) {
|
|
||||||
pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/decimal");
|
|
||||||
} else {
|
|
||||||
pushIgnoredContainer(qName);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "group":
|
case "group":
|
||||||
|
case "currencyDecimal":
|
||||||
|
case "currencyGroup":
|
||||||
// for FormatData
|
// for FormatData
|
||||||
// copy string for later assembly into NumberElements
|
// copy string for later assembly into NumberElements
|
||||||
if (currentContainer.getqName().equals("symbols")) {
|
if (currentContainer.getqName().equals("symbols")) {
|
||||||
pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/group");
|
pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/" + qName);
|
||||||
} else {
|
} else {
|
||||||
pushIgnoredContainer(qName);
|
pushIgnoredContainer(qName);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -136,14 +136,14 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
|
|||||||
* the same behavior as {@code "#,##0.0#;(#,##0.0#)"}.
|
* the same behavior as {@code "#,##0.0#;(#,##0.0#)"}.
|
||||||
*
|
*
|
||||||
* <p>The prefixes, suffixes, and various symbols used for infinity, digits,
|
* <p>The prefixes, suffixes, and various symbols used for infinity, digits,
|
||||||
* thousands separators, decimal separators, etc. may be set to arbitrary
|
* grouping separators, decimal separators, etc. may be set to arbitrary
|
||||||
* values, and they will appear properly during formatting. However, care must
|
* values, and they will appear properly during formatting. However, care must
|
||||||
* be taken that the symbols and strings do not conflict, or parsing will be
|
* be taken that the symbols and strings do not conflict, or parsing will be
|
||||||
* unreliable. For example, either the positive and negative prefixes or the
|
* unreliable. For example, either the positive and negative prefixes or the
|
||||||
* suffixes must be distinct for {@code DecimalFormat.parse()} to be able
|
* suffixes must be distinct for {@code DecimalFormat.parse()} to be able
|
||||||
* to distinguish positive from negative values. (If they are identical, then
|
* to distinguish positive from negative values. (If they are identical, then
|
||||||
* {@code DecimalFormat} will behave as if no negative subpattern was
|
* {@code DecimalFormat} will behave as if no negative subpattern was
|
||||||
* specified.) Another example is that the decimal separator and thousands
|
* specified.) Another example is that the decimal separator and grouping
|
||||||
* separator should be distinct characters, or parsing will be impossible.
|
* separator should be distinct characters, or parsing will be impossible.
|
||||||
*
|
*
|
||||||
* <p>The grouping separator is commonly used for thousands, but in some
|
* <p>The grouping separator is commonly used for thousands, but in some
|
||||||
@ -203,7 +203,7 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
|
|||||||
* <th scope="row">{@code ,}
|
* <th scope="row">{@code ,}
|
||||||
* <td>Number
|
* <td>Number
|
||||||
* <td>Yes
|
* <td>Yes
|
||||||
* <td>Grouping separator
|
* <td>Grouping separator or monetary grouping separator
|
||||||
* <tr style="vertical-align: top">
|
* <tr style="vertical-align: top">
|
||||||
* <th scope="row">{@code E}
|
* <th scope="row">{@code E}
|
||||||
* <td>Number
|
* <td>Number
|
||||||
@ -231,8 +231,8 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
|
|||||||
* <td>No
|
* <td>No
|
||||||
* <td>Currency sign, replaced by currency symbol. If
|
* <td>Currency sign, replaced by currency symbol. If
|
||||||
* doubled, replaced by international currency symbol.
|
* doubled, replaced by international currency symbol.
|
||||||
* If present in a pattern, the monetary decimal separator
|
* If present in a pattern, the monetary decimal/grouping separators
|
||||||
* is used instead of the decimal separator.
|
* are used instead of the decimal/grouping separators.
|
||||||
* <tr style="vertical-align:top">
|
* <tr style="vertical-align:top">
|
||||||
* <th scope="row">{@code '}
|
* <th scope="row">{@code '}
|
||||||
* <td>Prefix or suffix
|
* <td>Prefix or suffix
|
||||||
@ -1103,7 +1103,9 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
// Sets up the locale specific constants used when formatting.
|
// Sets up the locale specific constants used when formatting.
|
||||||
// '0' is our default representation of zero.
|
// '0' is our default representation of zero.
|
||||||
fastPathData.zeroDelta = symbols.getZeroDigit() - '0';
|
fastPathData.zeroDelta = symbols.getZeroDigit() - '0';
|
||||||
fastPathData.groupingChar = symbols.getGroupingSeparator();
|
fastPathData.groupingChar = isCurrencyFormat ?
|
||||||
|
symbols.getMonetaryGroupingSeparator() :
|
||||||
|
symbols.getGroupingSeparator();
|
||||||
|
|
||||||
// Sets up fractional constants related to currency/decimal pattern.
|
// Sets up fractional constants related to currency/decimal pattern.
|
||||||
fastPathData.fractionalMaxIntBound = (isCurrencyFormat)
|
fastPathData.fractionalMaxIntBound = (isCurrencyFormat)
|
||||||
@ -1774,7 +1776,9 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
int maxIntDigits, int minIntDigits,
|
int maxIntDigits, int minIntDigits,
|
||||||
int maxFraDigits, int minFraDigits) {
|
int maxFraDigits, int minFraDigits) {
|
||||||
|
|
||||||
char grouping = symbols.getGroupingSeparator();
|
char grouping = isCurrencyFormat ?
|
||||||
|
symbols.getMonetaryGroupingSeparator() :
|
||||||
|
symbols.getGroupingSeparator();
|
||||||
char zero = symbols.getZeroDigit();
|
char zero = symbols.getZeroDigit();
|
||||||
int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
|
int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
|
||||||
|
|
||||||
@ -2393,7 +2397,9 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
char decimal = isCurrencyFormat ?
|
char decimal = isCurrencyFormat ?
|
||||||
symbols.getMonetaryDecimalSeparator() :
|
symbols.getMonetaryDecimalSeparator() :
|
||||||
symbols.getDecimalSeparator();
|
symbols.getDecimalSeparator();
|
||||||
char grouping = symbols.getGroupingSeparator();
|
char grouping = isCurrencyFormat ?
|
||||||
|
symbols.getMonetaryGroupingSeparator() :
|
||||||
|
symbols.getGroupingSeparator();
|
||||||
String exponentString = symbols.getExponentSeparator();
|
String exponentString = symbols.getExponentSeparator();
|
||||||
boolean sawDecimal = false;
|
boolean sawDecimal = false;
|
||||||
boolean sawExponent = false;
|
boolean sawExponent = false;
|
||||||
@ -4061,7 +4067,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* True if this object represents a currency format. This determines
|
* True if this object represents a currency format. This determines
|
||||||
* whether the monetary decimal separator is used instead of the normal one.
|
* whether the monetary decimal/grouping separators are used instead of the normal ones.
|
||||||
*/
|
*/
|
||||||
private transient boolean isCurrencyFormat = false;
|
private transient boolean isCurrencyFormat = false;
|
||||||
|
|
||||||
@ -4346,8 +4352,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* The CURRENCY_SIGN is the standard Unicode symbol for currency. It
|
* The CURRENCY_SIGN is the standard Unicode symbol for currency. It
|
||||||
* is used in patterns and substituted with either the currency symbol,
|
* is used in patterns and substituted with either the currency symbol,
|
||||||
* or if it is doubled, with the international currency symbol. If the
|
* or if it is doubled, with the international currency symbol. If the
|
||||||
* CURRENCY_SIGN is seen in a pattern, then the decimal separator is
|
* CURRENCY_SIGN is seen in a pattern, then the decimal/grouping separators
|
||||||
* replaced with the monetary decimal separator.
|
* are replaced with the monetary decimal/grouping separators.
|
||||||
*
|
*
|
||||||
* The CURRENCY_SIGN is not localized.
|
* The CURRENCY_SIGN is not localized.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -202,11 +202,12 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param zeroDigit the character used for zero
|
* @param zeroDigit the character used for zero
|
||||||
*/
|
*/
|
||||||
public void setZeroDigit(char zeroDigit) {
|
public void setZeroDigit(char zeroDigit) {
|
||||||
|
hashCode = 0;
|
||||||
this.zeroDigit = zeroDigit;
|
this.zeroDigit = zeroDigit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the character used for thousands separator. Different for French, etc.
|
* Gets the character used for grouping separator. Different for French, etc.
|
||||||
*
|
*
|
||||||
* @return the grouping separator
|
* @return the grouping separator
|
||||||
*/
|
*/
|
||||||
@ -215,11 +216,12 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the character used for thousands separator. Different for French, etc.
|
* Sets the character used for grouping separator. Different for French, etc.
|
||||||
*
|
*
|
||||||
* @param groupingSeparator the grouping separator
|
* @param groupingSeparator the grouping separator
|
||||||
*/
|
*/
|
||||||
public void setGroupingSeparator(char groupingSeparator) {
|
public void setGroupingSeparator(char groupingSeparator) {
|
||||||
|
hashCode = 0;
|
||||||
this.groupingSeparator = groupingSeparator;
|
this.groupingSeparator = groupingSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +240,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param decimalSeparator the character used for decimal sign
|
* @param decimalSeparator the character used for decimal sign
|
||||||
*/
|
*/
|
||||||
public void setDecimalSeparator(char decimalSeparator) {
|
public void setDecimalSeparator(char decimalSeparator) {
|
||||||
|
hashCode = 0;
|
||||||
this.decimalSeparator = decimalSeparator;
|
this.decimalSeparator = decimalSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,44 +259,11 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param perMill the character used for per mille sign
|
* @param perMill the character used for per mille sign
|
||||||
*/
|
*/
|
||||||
public void setPerMill(char perMill) {
|
public void setPerMill(char perMill) {
|
||||||
|
hashCode = 0;
|
||||||
this.perMill = perMill;
|
this.perMill = perMill;
|
||||||
this.perMillText = Character.toString(perMill);
|
this.perMillText = Character.toString(perMill);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the string used for per mille sign. Different for Arabic, etc.
|
|
||||||
*
|
|
||||||
* @return the string used for per mille sign
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
String getPerMillText() {
|
|
||||||
return perMillText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the string used for per mille sign. Different for Arabic, etc.
|
|
||||||
*
|
|
||||||
* Setting the {@code perMillText} affects the return value of
|
|
||||||
* {@link #getPerMill()}, in which the first non-format character of
|
|
||||||
* {@code perMillText} is returned.
|
|
||||||
*
|
|
||||||
* @param perMillText the string used for per mille sign
|
|
||||||
* @throws NullPointerException if {@code perMillText} is null
|
|
||||||
* @throws IllegalArgumentException if {@code perMillText} is an empty string
|
|
||||||
* @see #getPerMill()
|
|
||||||
* @see #getPerMillText()
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
void setPerMillText(String perMillText) {
|
|
||||||
Objects.requireNonNull(perMillText);
|
|
||||||
if (perMillText.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Empty argument string");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.perMillText = perMillText;
|
|
||||||
this.perMill = findNonFormatChar(perMillText, '\u2030');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the character used for percent sign. Different for Arabic, etc.
|
* Gets the character used for percent sign. Different for Arabic, etc.
|
||||||
*
|
*
|
||||||
@ -309,44 +279,11 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param percent the character used for percent sign
|
* @param percent the character used for percent sign
|
||||||
*/
|
*/
|
||||||
public void setPercent(char percent) {
|
public void setPercent(char percent) {
|
||||||
|
hashCode = 0;
|
||||||
this.percent = percent;
|
this.percent = percent;
|
||||||
this.percentText = Character.toString(percent);
|
this.percentText = Character.toString(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the string used for percent sign. Different for Arabic, etc.
|
|
||||||
*
|
|
||||||
* @return the string used for percent sign
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
String getPercentText() {
|
|
||||||
return percentText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the string used for percent sign. Different for Arabic, etc.
|
|
||||||
*
|
|
||||||
* Setting the {@code percentText} affects the return value of
|
|
||||||
* {@link #getPercent()}, in which the first non-format character of
|
|
||||||
* {@code percentText} is returned.
|
|
||||||
*
|
|
||||||
* @param percentText the string used for percent sign
|
|
||||||
* @throws NullPointerException if {@code percentText} is null
|
|
||||||
* @throws IllegalArgumentException if {@code percentText} is an empty string
|
|
||||||
* @see #getPercent()
|
|
||||||
* @see #getPercentText()
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
void setPercentText(String percentText) {
|
|
||||||
Objects.requireNonNull(percentText);
|
|
||||||
if (percentText.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Empty argument string");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.percentText = percentText;
|
|
||||||
this.percent = findNonFormatChar(percentText, '%');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the character used for a digit in a pattern.
|
* Gets the character used for a digit in a pattern.
|
||||||
*
|
*
|
||||||
@ -362,6 +299,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param digit the character used for a digit in a pattern
|
* @param digit the character used for a digit in a pattern
|
||||||
*/
|
*/
|
||||||
public void setDigit(char digit) {
|
public void setDigit(char digit) {
|
||||||
|
hashCode = 0;
|
||||||
this.digit = digit;
|
this.digit = digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,6 +320,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param patternSeparator the pattern separator
|
* @param patternSeparator the pattern separator
|
||||||
*/
|
*/
|
||||||
public void setPatternSeparator(char patternSeparator) {
|
public void setPatternSeparator(char patternSeparator) {
|
||||||
|
hashCode = 0;
|
||||||
this.patternSeparator = patternSeparator;
|
this.patternSeparator = patternSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +341,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param infinity the string representing infinity
|
* @param infinity the string representing infinity
|
||||||
*/
|
*/
|
||||||
public void setInfinity(String infinity) {
|
public void setInfinity(String infinity) {
|
||||||
|
hashCode = 0;
|
||||||
this.infinity = infinity;
|
this.infinity = infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +362,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param NaN the string representing "not a number"
|
* @param NaN the string representing "not a number"
|
||||||
*/
|
*/
|
||||||
public void setNaN(String NaN) {
|
public void setNaN(String NaN) {
|
||||||
|
hashCode = 0;
|
||||||
this.NaN = NaN;
|
this.NaN = NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,49 +385,11 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* @param minusSign the character representing minus sign
|
* @param minusSign the character representing minus sign
|
||||||
*/
|
*/
|
||||||
public void setMinusSign(char minusSign) {
|
public void setMinusSign(char minusSign) {
|
||||||
|
hashCode = 0;
|
||||||
this.minusSign = minusSign;
|
this.minusSign = minusSign;
|
||||||
this.minusSignText = Character.toString(minusSign);
|
this.minusSignText = Character.toString(minusSign);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the string used to represent minus sign. If no explicit
|
|
||||||
* negative format is specified, one is formed by prefixing
|
|
||||||
* minusSignText to the positive format.
|
|
||||||
*
|
|
||||||
* @return the string representing minus sign
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
String getMinusSignText() {
|
|
||||||
return minusSignText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the string used to represent minus sign. If no explicit
|
|
||||||
* negative format is specified, one is formed by prefixing
|
|
||||||
* minusSignText to the positive format.
|
|
||||||
*
|
|
||||||
* Setting the {@code minusSignText} affects the return value of
|
|
||||||
* {@link #getMinusSign()}, in which the first non-format character of
|
|
||||||
* {@code minusSignText} is returned.
|
|
||||||
*
|
|
||||||
* @param minusSignText the character representing minus sign
|
|
||||||
* @throws NullPointerException if {@code minusSignText} is null
|
|
||||||
* @throws IllegalArgumentException if {@code minusSignText} is an
|
|
||||||
* empty string
|
|
||||||
* @see #getMinusSign()
|
|
||||||
* @see #getMinusSignText()
|
|
||||||
* @since 13
|
|
||||||
*/
|
|
||||||
void setMinusSignText(String minusSignText) {
|
|
||||||
Objects.requireNonNull(minusSignText);
|
|
||||||
if (minusSignText.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Empty argument string");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.minusSignText = minusSignText;
|
|
||||||
this.minusSign = findNonFormatChar(minusSignText, '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the currency symbol for the currency of these
|
* Returns the currency symbol for the currency of these
|
||||||
* DecimalFormatSymbols in their locale.
|
* DecimalFormatSymbols in their locale.
|
||||||
@ -510,6 +413,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
public void setCurrencySymbol(String currency)
|
public void setCurrencySymbol(String currency)
|
||||||
{
|
{
|
||||||
initializeCurrency(locale);
|
initializeCurrency(locale);
|
||||||
|
hashCode = 0;
|
||||||
currencySymbol = currency;
|
currencySymbol = currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,6 +449,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
public void setInternationalCurrencySymbol(String currencyCode)
|
public void setInternationalCurrencySymbol(String currencyCode)
|
||||||
{
|
{
|
||||||
initializeCurrency(locale);
|
initializeCurrency(locale);
|
||||||
|
hashCode = 0;
|
||||||
intlCurrencySymbol = currencyCode;
|
intlCurrencySymbol = currencyCode;
|
||||||
currency = null;
|
currency = null;
|
||||||
if (currencyCode != null) {
|
if (currencyCode != null) {
|
||||||
@ -586,6 +491,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
initializeCurrency(locale);
|
initializeCurrency(locale);
|
||||||
|
hashCode = 0;
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
intlCurrencySymbol = currency.getCurrencyCode();
|
intlCurrencySymbol = currency.getCurrencyCode();
|
||||||
currencySymbol = currency.getSymbol(locale);
|
currencySymbol = currency.getSymbol(locale);
|
||||||
@ -611,21 +517,10 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
*/
|
*/
|
||||||
public void setMonetaryDecimalSeparator(char sep)
|
public void setMonetaryDecimalSeparator(char sep)
|
||||||
{
|
{
|
||||||
|
hashCode = 0;
|
||||||
monetarySeparator = sep;
|
monetarySeparator = sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
|
||||||
// BEGIN Package Private methods ... to be made public later
|
|
||||||
//------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the character used to separate the mantissa from the exponent.
|
|
||||||
*/
|
|
||||||
char getExponentialSymbol()
|
|
||||||
{
|
|
||||||
return exponential;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the string used to separate the mantissa from the exponent.
|
* Returns the string used to separate the mantissa from the exponent.
|
||||||
* Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
|
* Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
|
||||||
@ -639,14 +534,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
return exponentialSeparator;
|
return exponentialSeparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the character used to separate the mantissa from the exponent.
|
|
||||||
*/
|
|
||||||
void setExponentialSymbol(char exp)
|
|
||||||
{
|
|
||||||
exponential = exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the string used to separate the mantissa from the exponent.
|
* Sets the string used to separate the mantissa from the exponent.
|
||||||
* Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
|
* Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
|
||||||
@ -661,9 +548,166 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
if (exp == null) {
|
if (exp == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
|
hashCode = 0;
|
||||||
exponentialSeparator = exp;
|
exponentialSeparator = exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the character used for grouping separator for currencies.
|
||||||
|
* May be different from {@code grouping separator} in some locales,
|
||||||
|
* e.g, German in Austria.
|
||||||
|
*
|
||||||
|
* @return the monetary grouping separator
|
||||||
|
* @since 15
|
||||||
|
*/
|
||||||
|
public char getMonetaryGroupingSeparator() {
|
||||||
|
return monetaryGroupingSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character used for grouping separator for currencies.
|
||||||
|
* Invocation of this method will not affect the normal
|
||||||
|
* {@code grouping separator}.
|
||||||
|
*
|
||||||
|
* @param monetaryGroupingSeparator the monetary grouping separator
|
||||||
|
* @see #setGroupingSeparator(char)
|
||||||
|
* @since 15
|
||||||
|
*/
|
||||||
|
public void setMonetaryGroupingSeparator(char monetaryGroupingSeparator)
|
||||||
|
{
|
||||||
|
hashCode = 0;
|
||||||
|
this.monetaryGroupingSeparator = monetaryGroupingSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// BEGIN Package Private methods ... to be made public later
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the character used to separate the mantissa from the exponent.
|
||||||
|
*/
|
||||||
|
char getExponentialSymbol()
|
||||||
|
{
|
||||||
|
return exponential;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character used to separate the mantissa from the exponent.
|
||||||
|
*/
|
||||||
|
void setExponentialSymbol(char exp)
|
||||||
|
{
|
||||||
|
exponential = exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the string used for per mille sign. Different for Arabic, etc.
|
||||||
|
*
|
||||||
|
* @return the string used for per mille sign
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
String getPerMillText() {
|
||||||
|
return perMillText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string used for per mille sign. Different for Arabic, etc.
|
||||||
|
*
|
||||||
|
* Setting the {@code perMillText} affects the return value of
|
||||||
|
* {@link #getPerMill()}, in which the first non-format character of
|
||||||
|
* {@code perMillText} is returned.
|
||||||
|
*
|
||||||
|
* @param perMillText the string used for per mille sign
|
||||||
|
* @throws NullPointerException if {@code perMillText} is null
|
||||||
|
* @throws IllegalArgumentException if {@code perMillText} is an empty string
|
||||||
|
* @see #getPerMill()
|
||||||
|
* @see #getPerMillText()
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
void setPerMillText(String perMillText) {
|
||||||
|
Objects.requireNonNull(perMillText);
|
||||||
|
if (perMillText.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Empty argument string");
|
||||||
|
}
|
||||||
|
|
||||||
|
hashCode = 0;
|
||||||
|
this.perMillText = perMillText;
|
||||||
|
this.perMill = findNonFormatChar(perMillText, '\u2030');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the string used for percent sign. Different for Arabic, etc.
|
||||||
|
*
|
||||||
|
* @return the string used for percent sign
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
String getPercentText() {
|
||||||
|
return percentText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string used for percent sign. Different for Arabic, etc.
|
||||||
|
*
|
||||||
|
* Setting the {@code percentText} affects the return value of
|
||||||
|
* {@link #getPercent()}, in which the first non-format character of
|
||||||
|
* {@code percentText} is returned.
|
||||||
|
*
|
||||||
|
* @param percentText the string used for percent sign
|
||||||
|
* @throws NullPointerException if {@code percentText} is null
|
||||||
|
* @throws IllegalArgumentException if {@code percentText} is an empty string
|
||||||
|
* @see #getPercent()
|
||||||
|
* @see #getPercentText()
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
void setPercentText(String percentText) {
|
||||||
|
Objects.requireNonNull(percentText);
|
||||||
|
if (percentText.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Empty argument string");
|
||||||
|
}
|
||||||
|
|
||||||
|
hashCode = 0;
|
||||||
|
this.percentText = percentText;
|
||||||
|
this.percent = findNonFormatChar(percentText, '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the string used to represent minus sign. If no explicit
|
||||||
|
* negative format is specified, one is formed by prefixing
|
||||||
|
* minusSignText to the positive format.
|
||||||
|
*
|
||||||
|
* @return the string representing minus sign
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
String getMinusSignText() {
|
||||||
|
return minusSignText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the string used to represent minus sign. If no explicit
|
||||||
|
* negative format is specified, one is formed by prefixing
|
||||||
|
* minusSignText to the positive format.
|
||||||
|
*
|
||||||
|
* Setting the {@code minusSignText} affects the return value of
|
||||||
|
* {@link #getMinusSign()}, in which the first non-format character of
|
||||||
|
* {@code minusSignText} is returned.
|
||||||
|
*
|
||||||
|
* @param minusSignText the character representing minus sign
|
||||||
|
* @throws NullPointerException if {@code minusSignText} is null
|
||||||
|
* @throws IllegalArgumentException if {@code minusSignText} is an
|
||||||
|
* empty string
|
||||||
|
* @see #getMinusSign()
|
||||||
|
* @see #getMinusSignText()
|
||||||
|
* @since 13
|
||||||
|
*/
|
||||||
|
void setMinusSignText(String minusSignText) {
|
||||||
|
Objects.requireNonNull(minusSignText);
|
||||||
|
if (minusSignText.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Empty argument string");
|
||||||
|
}
|
||||||
|
|
||||||
|
hashCode = 0;
|
||||||
|
this.minusSignText = minusSignText;
|
||||||
|
this.minusSign = findNonFormatChar(minusSignText, '-');
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// END Package Private methods ... to be made public later
|
// END Package Private methods ... to be made public later
|
||||||
@ -708,6 +752,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
|
intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
|
||||||
currency == other.currency &&
|
currency == other.currency &&
|
||||||
monetarySeparator == other.monetarySeparator &&
|
monetarySeparator == other.monetarySeparator &&
|
||||||
|
monetaryGroupingSeparator == other.monetaryGroupingSeparator &&
|
||||||
exponentialSeparator.equals(other.exponentialSeparator) &&
|
exponentialSeparator.equals(other.exponentialSeparator) &&
|
||||||
locale.equals(other.locale));
|
locale.equals(other.locale));
|
||||||
}
|
}
|
||||||
@ -715,12 +760,33 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
/**
|
/**
|
||||||
* Override hashCode.
|
* Override hashCode.
|
||||||
*/
|
*/
|
||||||
|
private volatile int hashCode;
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = zeroDigit;
|
if (hashCode == 0) {
|
||||||
result = result * 37 + groupingSeparator;
|
hashCode = Objects.hash(
|
||||||
result = result * 37 + decimalSeparator;
|
zeroDigit,
|
||||||
return result;
|
groupingSeparator,
|
||||||
|
decimalSeparator,
|
||||||
|
percent,
|
||||||
|
percentText,
|
||||||
|
perMill,
|
||||||
|
perMillText,
|
||||||
|
digit,
|
||||||
|
minusSign,
|
||||||
|
minusSignText,
|
||||||
|
patternSeparator,
|
||||||
|
infinity,
|
||||||
|
NaN,
|
||||||
|
getCurrencySymbol(), // possible currency init occurs here
|
||||||
|
intlCurrencySymbol,
|
||||||
|
currency,
|
||||||
|
monetarySeparator,
|
||||||
|
monetaryGroupingSeparator,
|
||||||
|
exponentialSeparator,
|
||||||
|
locale);
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -759,14 +825,15 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
infinity = numberElements[9];
|
infinity = numberElements[9];
|
||||||
NaN = numberElements[10];
|
NaN = numberElements[10];
|
||||||
|
|
||||||
|
// monetary decimal/grouping separators may be missing in resource bundles
|
||||||
|
monetarySeparator = numberElements.length < 12 || numberElements[11].isEmpty() ?
|
||||||
|
decimalSeparator : numberElements[11].charAt(0);
|
||||||
|
monetaryGroupingSeparator = numberElements.length < 13 || numberElements[12].isEmpty() ?
|
||||||
|
groupingSeparator : numberElements[12].charAt(0);
|
||||||
|
|
||||||
// maybe filled with previously cached values, or null.
|
// maybe filled with previously cached values, or null.
|
||||||
intlCurrencySymbol = (String) data[1];
|
intlCurrencySymbol = (String) data[1];
|
||||||
currencySymbol = (String) data[2];
|
currencySymbol = (String) data[2];
|
||||||
|
|
||||||
// Currently the monetary decimal separator is the same as the
|
|
||||||
// standard decimal separator for all locales that we support.
|
|
||||||
// If that changes, add a new entry to NumberElements.
|
|
||||||
monetarySeparator = decimalSeparator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -844,6 +911,8 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* {@code perMillText}, {@code percentText}, and
|
* {@code perMillText}, {@code percentText}, and
|
||||||
* {@code minusSignText} using {@code perMill}, {@code percent}, and
|
* {@code minusSignText} using {@code perMill}, {@code percent}, and
|
||||||
* {@code minusSign} respectively.
|
* {@code minusSign} respectively.
|
||||||
|
* If {@code serialVersionOnStream} is less than 5, it initializes
|
||||||
|
* {@code monetaryGroupingSeparator} using {@code groupingSeparator}.
|
||||||
* Sets {@code serialVersionOnStream} back to the maximum allowed value so that
|
* Sets {@code serialVersionOnStream} back to the maximum allowed value so that
|
||||||
* default serialization will work properly if this object is streamed out again.
|
* default serialization will work properly if this object is streamed out again.
|
||||||
* Initializes the currency from the intlCurrencySymbol field.
|
* Initializes the currency from the intlCurrencySymbol field.
|
||||||
@ -886,6 +955,10 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
"per mille, and/or minus sign disagree.");
|
"per mille, and/or minus sign disagree.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (serialVersionOnStream < 5) {
|
||||||
|
// didn't have monetaryGroupingSeparator. Create one using groupingSeparator
|
||||||
|
monetaryGroupingSeparator = groupingSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
serialVersionOnStream = currentSerialVersion;
|
serialVersionOnStream = currentSerialVersion;
|
||||||
|
|
||||||
@ -907,7 +980,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
private char zeroDigit;
|
private char zeroDigit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Character used for thousands separator.
|
* Character used for grouping separator.
|
||||||
*
|
*
|
||||||
* @serial
|
* @serial
|
||||||
* @see #getGroupingSeparator
|
* @see #getGroupingSeparator
|
||||||
@ -1063,6 +1136,14 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
*/
|
*/
|
||||||
private String minusSignText;
|
private String minusSignText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The grouping separator used when formatting currency values.
|
||||||
|
*
|
||||||
|
* @serial
|
||||||
|
* @since 15
|
||||||
|
*/
|
||||||
|
private char monetaryGroupingSeparator;
|
||||||
|
|
||||||
// currency; only the ISO code is serialized.
|
// currency; only the ISO code is serialized.
|
||||||
private transient Currency currency;
|
private transient Currency currency;
|
||||||
private transient volatile boolean currencyInitialized;
|
private transient volatile boolean currencyInitialized;
|
||||||
@ -1079,7 +1160,8 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
// - 3 for version from J2SE 1.6, which includes exponentialSeparator field.
|
// - 3 for version from J2SE 1.6, which includes exponentialSeparator field.
|
||||||
// - 4 for version from Java SE 13, which includes perMillText, percentText,
|
// - 4 for version from Java SE 13, which includes perMillText, percentText,
|
||||||
// and minusSignText field.
|
// and minusSignText field.
|
||||||
private static final int currentSerialVersion = 4;
|
// - 5 for version from Java SE 15, which includes monetaryGroupingSeparator.
|
||||||
|
private static final int currentSerialVersion = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the version of {@code DecimalFormatSymbols} present on the stream.
|
* Describes the version of {@code DecimalFormatSymbols} present on the stream.
|
||||||
@ -1096,7 +1178,9 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
|
|||||||
* <li><b>4</b>: Versions written by Java SE 13 or later, which include
|
* <li><b>4</b>: Versions written by Java SE 13 or later, which include
|
||||||
* new {@code perMillText}, {@code percentText}, and
|
* new {@code perMillText}, {@code percentText}, and
|
||||||
* {@code minusSignText} field.
|
* {@code minusSignText} field.
|
||||||
* </ul>
|
* <li><b>5</b>: Versions written by Java SE 15 or later, which include
|
||||||
|
* new {@code monetaryGroupingSeparator} field.
|
||||||
|
* * </ul>
|
||||||
* When streaming out a {@code DecimalFormatSymbols}, the most recent format
|
* When streaming out a {@code DecimalFormatSymbols}, the most recent format
|
||||||
* (corresponding to the highest allowable {@code serialVersionOnStream})
|
* (corresponding to the highest allowable {@code serialVersionOnStream})
|
||||||
* is always written.
|
* is always written.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,10 +23,11 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4290801 4942982 5102005 8008577 8021121 8210153
|
* @bug 4290801 4942982 5102005 8008577 8021121 8210153 8227313
|
||||||
* @summary Basic tests for currency formatting.
|
* @summary Basic tests for currency formatting.
|
||||||
* @modules jdk.localedata
|
* @modules jdk.localedata
|
||||||
* @run main/othervm -Djava.locale.providers=JRE,SPI CurrencyFormat
|
* @run main/othervm -Djava.locale.providers=COMPAT CurrencyFormat COMPAT
|
||||||
|
* @run main/othervm -Djava.locale.providers=CLDR CurrencyFormat CLDR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -42,7 +43,10 @@ import java.text.SimpleDateFormat;
|
|||||||
|
|
||||||
public class CurrencyFormat {
|
public class CurrencyFormat {
|
||||||
|
|
||||||
|
private static boolean isCompat;
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
isCompat = "COMPAT".equals(args[0]);
|
||||||
testFormatting();
|
testFormatting();
|
||||||
testSymbols();
|
testSymbols();
|
||||||
}
|
}
|
||||||
@ -54,7 +58,10 @@ public class CurrencyFormat {
|
|||||||
Locale.JAPAN,
|
Locale.JAPAN,
|
||||||
Locale.GERMANY,
|
Locale.GERMANY,
|
||||||
Locale.ITALY,
|
Locale.ITALY,
|
||||||
new Locale("it", "IT", "EURO") };
|
new Locale("it", "IT", "EURO"),
|
||||||
|
Locale.forLanguageTag("de-AT"),
|
||||||
|
Locale.forLanguageTag("fr-CH"),
|
||||||
|
};
|
||||||
Currency[] currencies = {
|
Currency[] currencies = {
|
||||||
null,
|
null,
|
||||||
Currency.getInstance("USD"),
|
Currency.getInstance("USD"),
|
||||||
@ -68,6 +75,17 @@ public class CurrencyFormat {
|
|||||||
{"1.234,56 \u20AC", "1.234,56 USD", "1.235 JPY", "1.234,56 DM", "1.234,56 \u20AC"},
|
{"1.234,56 \u20AC", "1.234,56 USD", "1.235 JPY", "1.234,56 DM", "1.234,56 \u20AC"},
|
||||||
{"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
|
{"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
|
||||||
{"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
|
{"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
|
||||||
|
{"\u20AC 1.234,56", "USD 1.234,56", "JPY 1.235", "DEM 1.234,56", "\u20AC 1.234,56"},
|
||||||
|
{"SFr. 1'234.56", "USD 1'234.56", "JPY 1'235", "DEM 1'234.56", "EUR 1'234.56"},
|
||||||
|
};
|
||||||
|
String[][] expecteds_cldr = {
|
||||||
|
{"$1,234.56", "$1,234.56", "\u00a51,235", "DEM1,234.56", "\u20ac1,234.56"},
|
||||||
|
{"\uFFE51,235", "$1,234.56", "\uFFE51,235", "DEM1,234.56", "\u20ac1,234.56"},
|
||||||
|
{"1.234,56\u00a0\u20ac", "1.234,56\u00a0$", "1.235\u00a0\u00a5", "1.234,56\u00a0DM", "1.234,56\u00a0\u20ac"},
|
||||||
|
{"1.234,56\u00a0\u20ac", "1.234,56\u00a0USD", "1.235\u00a0JPY", "1.234,56\u00a0DEM", "1.234,56\u00a0\u20ac"},
|
||||||
|
{"1.234,56\u00a0\u20ac", "1.234,56\u00a0USD", "1.235\u00a0JPY", "1.234,56\u00a0DEM", "1.234,56\u00a0\u20ac"},
|
||||||
|
{"\u20ac\u00a01.234,56", "$\u00a01.234,56", "\u00a5\u00a01.235", "DM\u00a01.234,56", "\u20ac\u00a01.234,56"},
|
||||||
|
{"1\u202f234.56\u00a0CHF", "1\u202f234.56\u00a0$US", "1\u202f235\u00a0JPY", "1\u202f234.56\u00a0DEM", "1\u202f234.56\u00a0\u20ac"},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < locales.length; i++) {
|
for (int i = 0; i < locales.length; i++) {
|
||||||
@ -75,7 +93,7 @@ public class CurrencyFormat {
|
|||||||
NumberFormat format = NumberFormat.getCurrencyInstance(locale);
|
NumberFormat format = NumberFormat.getCurrencyInstance(locale);
|
||||||
for (int j = 0; j < currencies.length; j++) {
|
for (int j = 0; j < currencies.length; j++) {
|
||||||
Currency currency = currencies[j];
|
Currency currency = currencies[j];
|
||||||
String expected = expecteds[i][j];
|
String expected = isCompat ? expecteds[i][j] : expecteds_cldr[i][j];
|
||||||
if (currency != null) {
|
if (currency != null) {
|
||||||
format.setCurrency(currency);
|
format.setCurrency(currency);
|
||||||
int digits = currency.getDefaultFractionDigits();
|
int digits = currency.getDefaultFractionDigits();
|
||||||
@ -99,6 +117,11 @@ public class CurrencyFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void testSymbols() throws Exception {
|
static void testSymbols() throws Exception {
|
||||||
|
if (!isCompat) {
|
||||||
|
// For COMPAT only.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
FileInputStream stream = new FileInputStream(new File(System.getProperty("test.src", "."), "CurrencySymbols.properties"));
|
FileInputStream stream = new FileInputStream(new File(System.getProperty("test.src", "."), "CurrencySymbols.properties"));
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
props.load(stream);
|
props.load(stream);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,7 +29,7 @@
|
|||||||
* 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840
|
* 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840
|
||||||
* 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198
|
* 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198
|
||||||
* 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742
|
* 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742
|
||||||
* 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577
|
* 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313
|
||||||
* @summary Regression tests for NumberFormat and associated classes
|
* @summary Regression tests for NumberFormat and associated classes
|
||||||
* @library /java/text/testlib
|
* @library /java/text/testlib
|
||||||
* @build IntlTest HexDumpReader TestUtils
|
* @build IntlTest HexDumpReader TestUtils
|
||||||
@ -1802,6 +1802,66 @@ public class NumberRegression extends IntlTest {
|
|||||||
}
|
}
|
||||||
Locale.setDefault(savedLocale);
|
Locale.setDefault(savedLocale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for get/setMonetaryGroupingSeparator() methods.
|
||||||
|
* @since 15
|
||||||
|
*/
|
||||||
|
public void test8227313() throws ParseException {
|
||||||
|
var nrmSep = 'n';
|
||||||
|
var monSep = 'm';
|
||||||
|
var curSym = "Cur";
|
||||||
|
var inputNum = 10;
|
||||||
|
var nrmPattern = ",#";
|
||||||
|
var monPattern = "\u00a4 ,#";
|
||||||
|
var expectedNrmFmt = "1n0";
|
||||||
|
var expectedMonFmt = "Cur 1m0";
|
||||||
|
|
||||||
|
var ndfs = DecimalFormatSymbols.getInstance();
|
||||||
|
ndfs.setGroupingSeparator(nrmSep);
|
||||||
|
var nf = new DecimalFormat(nrmPattern, ndfs);
|
||||||
|
var mdfs = DecimalFormatSymbols.getInstance();
|
||||||
|
mdfs.setMonetaryGroupingSeparator(monSep);
|
||||||
|
mdfs.setCurrencySymbol(curSym);
|
||||||
|
var mf = new DecimalFormat(monPattern, mdfs);
|
||||||
|
|
||||||
|
// get test
|
||||||
|
char gotNrmSep = mdfs.getGroupingSeparator();
|
||||||
|
char gotMonSep = mdfs.getMonetaryGroupingSeparator();
|
||||||
|
if (gotMonSep != monSep) {
|
||||||
|
errln("FAIL: getMonetaryGroupingSeparator() returned incorrect value. expected: "
|
||||||
|
+ monSep + ", got: " + gotMonSep);
|
||||||
|
}
|
||||||
|
if (gotMonSep == gotNrmSep) {
|
||||||
|
errln("FAIL: getMonetaryGroupingSeparator() returned the same value with " +
|
||||||
|
"getGroupingSeparator(): monetary sep: " + gotMonSep +
|
||||||
|
", normal sep: " + gotNrmSep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// format test
|
||||||
|
var formatted = mf.format(inputNum);
|
||||||
|
if (!formatted.equals(expectedMonFmt)) {
|
||||||
|
errln("FAIL: format failed. expected: " + expectedMonFmt +
|
||||||
|
", got: " + formatted);
|
||||||
|
}
|
||||||
|
formatted = nf.format(inputNum);
|
||||||
|
if (!formatted.equals(expectedNrmFmt)) {
|
||||||
|
errln("FAIL: normal format failed. expected: " + expectedNrmFmt +
|
||||||
|
", got: " + formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse test
|
||||||
|
Number parsed = mf.parse(expectedMonFmt);
|
||||||
|
if (parsed.intValue() != inputNum) {
|
||||||
|
errln("FAIL: parse failed. expected: " + inputNum +
|
||||||
|
", got: " + parsed);
|
||||||
|
}
|
||||||
|
parsed = nf.parse(expectedNrmFmt);
|
||||||
|
if (parsed.intValue() != inputNum) {
|
||||||
|
errln("FAIL: normal parse failed. expected: " + inputNum +
|
||||||
|
", got: " + parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
|
@ -8388,3 +8388,9 @@ FormatData/es_CL/MonthAbbreviations/8=sep.
|
|||||||
FormatData/es_CL/standalone.MonthAbbreviations/8=sept.
|
FormatData/es_CL/standalone.MonthAbbreviations/8=sept.
|
||||||
FormatData/es_CO/MonthAbbreviations/8=sep.
|
FormatData/es_CO/MonthAbbreviations/8=sep.
|
||||||
FormatData/es_CO/standalone.MonthAbbreviations/8=sept.
|
FormatData/es_CO/standalone.MonthAbbreviations/8=sept.
|
||||||
|
|
||||||
|
# bug # 8227313
|
||||||
|
FormatData/de/latn.NumberElements/12=
|
||||||
|
FormatData/de_AT/latn.NumberElements/12=.
|
||||||
|
FormatData/fr/latn.NumberElements/11=
|
||||||
|
FormatData/fr_CH/latn.NumberElements/11=.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user