ICU-10640 Carry rounding measure amounts down except the last to the JAVA implementation.
X-SVN-Rev: 35182
This commit is contained in:
parent
8b58bace5e
commit
d09b746a61
@ -31,6 +31,7 @@ import com.ibm.icu.impl.DontCareFieldPosition;
|
|||||||
import com.ibm.icu.impl.ICUResourceBundle;
|
import com.ibm.icu.impl.ICUResourceBundle;
|
||||||
import com.ibm.icu.impl.SimpleCache;
|
import com.ibm.icu.impl.SimpleCache;
|
||||||
import com.ibm.icu.impl.SimplePatternFormatter;
|
import com.ibm.icu.impl.SimplePatternFormatter;
|
||||||
|
import com.ibm.icu.math.BigDecimal;
|
||||||
import com.ibm.icu.util.Currency;
|
import com.ibm.icu.util.Currency;
|
||||||
import com.ibm.icu.util.CurrencyAmount;
|
import com.ibm.icu.util.CurrencyAmount;
|
||||||
import com.ibm.icu.util.Measure;
|
import com.ibm.icu.util.Measure;
|
||||||
@ -121,6 +122,8 @@ public class MeasureFormat extends UFormat {
|
|||||||
private final transient NumericFormatters numericFormatters;
|
private final transient NumericFormatters numericFormatters;
|
||||||
|
|
||||||
private final transient ImmutableNumberFormat currencyFormat;
|
private final transient ImmutableNumberFormat currencyFormat;
|
||||||
|
|
||||||
|
private final transient ImmutableNumberFormat integerFormat;
|
||||||
|
|
||||||
private static final SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>> localeToUnitToStyleToCountToFormat
|
private static final SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>> localeToUnitToStyleToCountToFormat
|
||||||
= new SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>>();
|
= new SimpleCache<ULocale,Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>>>();
|
||||||
@ -247,7 +250,10 @@ public class MeasureFormat extends UFormat {
|
|||||||
localeToNumericDurationFormatters.put(locale, formatters);
|
localeToNumericDurationFormatters.put(locale, formatters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NumberFormat intFormat = NumberFormat.getInstance(locale);
|
||||||
|
intFormat.setMaximumFractionDigits(0);
|
||||||
|
intFormat.setMinimumFractionDigits(0);
|
||||||
|
intFormat.setRoundingMode(BigDecimal.ROUND_DOWN);
|
||||||
return new MeasureFormat(
|
return new MeasureFormat(
|
||||||
locale,
|
locale,
|
||||||
formatWidth,
|
formatWidth,
|
||||||
@ -256,7 +262,8 @@ public class MeasureFormat extends UFormat {
|
|||||||
unitToStyleToCountToFormat,
|
unitToStyleToCountToFormat,
|
||||||
formatters,
|
formatters,
|
||||||
new ImmutableNumberFormat(
|
new ImmutableNumberFormat(
|
||||||
NumberFormat.getInstance(locale, formatWidth.getCurrencyStyle())));
|
NumberFormat.getInstance(locale, formatWidth.getCurrencyStyle())),
|
||||||
|
new ImmutableNumberFormat(intFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -297,7 +304,7 @@ public class MeasureFormat extends UFormat {
|
|||||||
} else if (obj instanceof Measure[]) {
|
} else if (obj instanceof Measure[]) {
|
||||||
toAppendTo.append(formatMeasures(new StringBuilder(), fpos, (Measure[]) obj));
|
toAppendTo.append(formatMeasures(new StringBuilder(), fpos, (Measure[]) obj));
|
||||||
} else if (obj instanceof Measure){
|
} else if (obj instanceof Measure){
|
||||||
toAppendTo.append(formatMeasure((Measure) obj, new StringBuilder(), fpos));
|
toAppendTo.append(formatMeasure((Measure) obj, numberFormat, new StringBuilder(), fpos));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(obj.toString());
|
throw new IllegalArgumentException(obj.toString());
|
||||||
}
|
}
|
||||||
@ -362,7 +369,7 @@ public class MeasureFormat extends UFormat {
|
|||||||
return appendTo;
|
return appendTo;
|
||||||
}
|
}
|
||||||
if (measures.length == 1) {
|
if (measures.length == 1) {
|
||||||
return formatMeasure(measures[0], appendTo, fieldPosition);
|
return formatMeasure(measures[0], numberFormat, appendTo, fieldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formatWidth == FormatWidth.NUMERIC) {
|
if (formatWidth == FormatWidth.NUMERIC) {
|
||||||
@ -382,7 +389,9 @@ public class MeasureFormat extends UFormat {
|
|||||||
// Fast track: No field position.
|
// Fast track: No field position.
|
||||||
String[] results = new String[measures.length];
|
String[] results = new String[measures.length];
|
||||||
for (int i = 0; i < measures.length; i++) {
|
for (int i = 0; i < measures.length; i++) {
|
||||||
results[i] = formatMeasure(measures[i]);
|
results[i] = formatMeasure(
|
||||||
|
measures[i],
|
||||||
|
i == measures.length - 1 ? numberFormat : integerFormat);
|
||||||
}
|
}
|
||||||
return appendTo.append(listFormatter.format((Object[]) results));
|
return appendTo.append(listFormatter.format((Object[]) results));
|
||||||
|
|
||||||
@ -482,7 +491,8 @@ public class MeasureFormat extends UFormat {
|
|||||||
this.rules,
|
this.rules,
|
||||||
this.unitToStyleToCountToFormat,
|
this.unitToStyleToCountToFormat,
|
||||||
this.numericFormatters,
|
this.numericFormatters,
|
||||||
this.currencyFormat);
|
this.currencyFormat,
|
||||||
|
this.integerFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MeasureFormat(
|
private MeasureFormat(
|
||||||
@ -492,7 +502,8 @@ public class MeasureFormat extends UFormat {
|
|||||||
PluralRules rules,
|
PluralRules rules,
|
||||||
Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>> unitToStyleToCountToFormat,
|
Map<MeasureUnit, EnumMap<FormatWidth, QuantityFormatter>> unitToStyleToCountToFormat,
|
||||||
NumericFormatters formatters,
|
NumericFormatters formatters,
|
||||||
ImmutableNumberFormat currencyFormat) {
|
ImmutableNumberFormat currencyFormat,
|
||||||
|
ImmutableNumberFormat integerFormat) {
|
||||||
setLocale(locale, locale);
|
setLocale(locale, locale);
|
||||||
this.formatWidth = formatWidth;
|
this.formatWidth = formatWidth;
|
||||||
this.numberFormat = format;
|
this.numberFormat = format;
|
||||||
@ -500,6 +511,7 @@ public class MeasureFormat extends UFormat {
|
|||||||
this.unitToStyleToCountToFormat = unitToStyleToCountToFormat;
|
this.unitToStyleToCountToFormat = unitToStyleToCountToFormat;
|
||||||
this.numericFormatters = formatters;
|
this.numericFormatters = formatters;
|
||||||
this.currencyFormat = currencyFormat;
|
this.currencyFormat = currencyFormat;
|
||||||
|
this.integerFormat = integerFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeasureFormat() {
|
MeasureFormat() {
|
||||||
@ -510,6 +522,7 @@ public class MeasureFormat extends UFormat {
|
|||||||
this.unitToStyleToCountToFormat = null;
|
this.unitToStyleToCountToFormat = null;
|
||||||
this.numericFormatters = null;
|
this.numericFormatters = null;
|
||||||
this.currencyFormat = null;
|
this.currencyFormat = null;
|
||||||
|
this.integerFormat = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NumericFormatters {
|
static class NumericFormatters {
|
||||||
@ -601,14 +614,17 @@ public class MeasureFormat extends UFormat {
|
|||||||
return unitToStyleToCountToFormat;
|
return unitToStyleToCountToFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatMeasure(Measure measure) {
|
private String formatMeasure(Measure measure, ImmutableNumberFormat nf) {
|
||||||
return formatMeasure(
|
return formatMeasure(
|
||||||
measure, new StringBuilder(),
|
measure, nf, new StringBuilder(),
|
||||||
DontCareFieldPosition.INSTANCE).toString();
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuilder formatMeasure(
|
private StringBuilder formatMeasure(
|
||||||
Measure measure, StringBuilder appendTo, FieldPosition fieldPosition) {
|
Measure measure,
|
||||||
|
ImmutableNumberFormat nf,
|
||||||
|
StringBuilder appendTo,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
if (measure.getUnit() instanceof Currency) {
|
if (measure.getUnit() instanceof Currency) {
|
||||||
return appendTo.append(
|
return appendTo.append(
|
||||||
currencyFormat.format(
|
currencyFormat.format(
|
||||||
@ -620,7 +636,7 @@ public class MeasureFormat extends UFormat {
|
|||||||
Number n = measure.getNumber();
|
Number n = measure.getNumber();
|
||||||
MeasureUnit unit = measure.getUnit();
|
MeasureUnit unit = measure.getUnit();
|
||||||
UFieldPosition fpos = new UFieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
|
UFieldPosition fpos = new UFieldPosition(fieldPosition.getFieldAttribute(), fieldPosition.getField());
|
||||||
StringBuffer formattedNumber = numberFormat.format(n, new StringBuffer(), fpos);
|
StringBuffer formattedNumber = nf.format(n, new StringBuffer(), fpos);
|
||||||
String keyword = rules.select(new PluralRules.FixedDecimal(n.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
|
String keyword = rules.select(new PluralRules.FixedDecimal(n.doubleValue(), fpos.getCountVisibleFractionDigits(), fpos.getFractionDigits()));
|
||||||
|
|
||||||
Map<FormatWidth, QuantityFormatter> styleToCountToFormat = unitToStyleToCountToFormat.get(unit);
|
Map<FormatWidth, QuantityFormatter> styleToCountToFormat = unitToStyleToCountToFormat.get(unit);
|
||||||
@ -705,13 +721,14 @@ public class MeasureFormat extends UFormat {
|
|||||||
|
|
||||||
int fieldPositionFoundIndex = -1;
|
int fieldPositionFoundIndex = -1;
|
||||||
for (int i = 0; i < measures.length; ++i) {
|
for (int i = 0; i < measures.length; ++i) {
|
||||||
|
ImmutableNumberFormat nf = (i == measures.length - 1 ? numberFormat : integerFormat);
|
||||||
if (fieldPositionFoundIndex == -1) {
|
if (fieldPositionFoundIndex == -1) {
|
||||||
results[i] = formatMeasure(measures[i], new StringBuilder(), fpos).toString();
|
results[i] = formatMeasure(measures[i], nf, new StringBuilder(), fpos).toString();
|
||||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||||
fieldPositionFoundIndex = i;
|
fieldPositionFoundIndex = i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
results[i] = formatMeasure(measures[i]);
|
results[i] = formatMeasure(measures[i], nf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListFormatter.FormattedListBuilder builder =
|
ListFormatter.FormattedListBuilder builder =
|
||||||
|
@ -575,6 +575,29 @@ public class MeasureUnitTest extends TestFmwk {
|
|||||||
assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth());
|
assertEquals("getWidth", MeasureFormat.FormatWidth.WIDE, mf.getWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDoubleZero() {
|
||||||
|
ULocale en = new ULocale("en");
|
||||||
|
NumberFormat nf = NumberFormat.getInstance(en);
|
||||||
|
nf.setMinimumFractionDigits(2);
|
||||||
|
nf.setMaximumFractionDigits(2);
|
||||||
|
MeasureFormat mf = MeasureFormat.getInstance(en, FormatWidth.WIDE, nf);
|
||||||
|
assertEquals(
|
||||||
|
"Positive Rounding",
|
||||||
|
"4 hours, 23 minutes, 16.00 seconds",
|
||||||
|
mf.formatMeasures(
|
||||||
|
new Measure(4.7, MeasureUnit.HOUR),
|
||||||
|
new Measure(23, MeasureUnit.MINUTE),
|
||||||
|
new Measure(16, MeasureUnit.SECOND)));
|
||||||
|
assertEquals(
|
||||||
|
"Negative Rounding",
|
||||||
|
"-4 hours, 23 minutes, 16.00 seconds",
|
||||||
|
mf.formatMeasures(
|
||||||
|
new Measure(-4.7, MeasureUnit.HOUR),
|
||||||
|
new Measure(23, MeasureUnit.MINUTE),
|
||||||
|
new Measure(16, MeasureUnit.SECOND)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void generateCXXHConstants() {
|
static void generateCXXHConstants() {
|
||||||
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
|
Map<String, MeasureUnit> seen = new HashMap<String, MeasureUnit>();
|
||||||
TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>();
|
TreeMap<String, List<MeasureUnit>> allUnits = new TreeMap<String, List<MeasureUnit>>();
|
||||||
|
Loading…
Reference in New Issue
Block a user