ICU-11276 Assorted Java NumberRangeFormatter API improvements.
This commit is contained in:
parent
9924225ed6
commit
cc842512fa
@ -10,6 +10,7 @@ import java.util.Arrays;
|
||||
|
||||
import com.ibm.icu.impl.number.DecimalQuantity;
|
||||
import com.ibm.icu.impl.number.NumberStringBuilder;
|
||||
import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType;
|
||||
import com.ibm.icu.util.ICUUncheckedIOException;
|
||||
|
||||
/**
|
||||
@ -17,7 +18,7 @@ import com.ibm.icu.util.ICUUncheckedIOException;
|
||||
* including a String, an AttributedCharacterIterator, and a BigDecimal.
|
||||
*
|
||||
* @author sffc
|
||||
* @draft ICU 62
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
@ -27,10 +28,6 @@ public class FormattedNumberRange {
|
||||
final DecimalQuantity second;
|
||||
final RangeIdentityType identityType;
|
||||
|
||||
public static enum RangeIdentityType {
|
||||
EQUAL_BEFORE_ROUNDING, EQUAL_AFTER_ROUNDING, NOT_EQUAL
|
||||
}
|
||||
|
||||
FormattedNumberRange(NumberStringBuilder nsb, DecimalQuantity first, DecimalQuantity second,
|
||||
RangeIdentityType identityType) {
|
||||
this.nsb = nsb;
|
||||
@ -89,8 +86,8 @@ public class FormattedNumberRange {
|
||||
* multiple times, this method may be called repeatedly with the following pattern:
|
||||
*
|
||||
* <pre>
|
||||
* FieldPosition fpos = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
|
||||
* while (formattedNumber.nextFieldPosition(fpos, status)) {
|
||||
* FieldPosition fpos = new FieldPosition(NumberFormat.Field.INTEGER);
|
||||
* while (formattedNumberRange.nextFieldPosition(fpos, status)) {
|
||||
* // do something with fpos.
|
||||
* }
|
||||
* </pre>
|
||||
@ -162,7 +159,7 @@ public class FormattedNumberRange {
|
||||
* used. For example, if the first and second number were the same either before or after rounding occurred, an
|
||||
* identity fallback was used.
|
||||
*
|
||||
* @return A IdentityType indicating the resulting identity situation in the formatted number range.
|
||||
* @return A RangeIdentityType indicating the resulting identity situation in the formatted number range.
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
|
@ -6,7 +6,7 @@ import com.ibm.icu.impl.number.DecimalQuantity;
|
||||
import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
|
||||
import com.ibm.icu.impl.number.NumberStringBuilder;
|
||||
import com.ibm.icu.impl.number.range.RangeMacroProps;
|
||||
import com.ibm.icu.number.FormattedNumberRange.RangeIdentityType;
|
||||
import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityType;
|
||||
|
||||
/**
|
||||
* A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
|
||||
@ -30,7 +30,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
|
||||
* The first number in the range, usually to the left in LTR locales.
|
||||
* @param second
|
||||
* The second number in the range, usually to the right in LTR locales.
|
||||
* @return A FormattedNumber object; call .toString() to get the string.
|
||||
* @return A FormattedNumberRange object; call .toString() to get the string.
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
@ -49,7 +49,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
|
||||
* The first number in the range, usually to the left in LTR locales.
|
||||
* @param second
|
||||
* The second number in the range, usually to the right in LTR locales.
|
||||
* @return A FormattedNumber object; call .toString() to get the string.
|
||||
* @return A FormattedNumberRange object; call .toString() to get the string.
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
@ -70,7 +70,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
|
||||
* The first number in the range, usually to the left in LTR locales.
|
||||
* @param second
|
||||
* The second number in the range, usually to the right in LTR locales.
|
||||
* @return A FormattedNumber object; call .toString() to get the string.
|
||||
* @return A FormattedNumberRange object; call .toString() to get the string.
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
|
@ -8,6 +8,20 @@ import com.ibm.icu.util.ULocale;
|
||||
|
||||
/**
|
||||
* The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
|
||||
* <p>
|
||||
* Usage example:
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
* NumberRangeFormatter.with().identityFallback(RangeIdentityFallback.APPROXIMATELY_OR_SINGLE_VALUE)
|
||||
* .numberFormatterFirst(NumberFormatter.with().unit(MeasureUnit.METER))
|
||||
* .numberFormatterSecond(NumberFormatter.with().unit(MeasureUnit.KILOMETER)).locale(ULocale.UK)
|
||||
* .formatRange(750, 1.2).toString();
|
||||
* // => "750 m - 1.2 km"
|
||||
* </pre>
|
||||
* <p>
|
||||
* Like NumberFormatter, NumberRangeFormatter instances are immutable and thread-safe. This API is based on the
|
||||
* <em>fluent</em> design pattern popularized by libraries such as Google's Guava.
|
||||
*
|
||||
* @author sffc
|
||||
* @draft ICU 63
|
||||
@ -72,7 +86,7 @@ public abstract class NumberRangeFormatter {
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
public enum IdentityFallback {
|
||||
public static enum RangeIdentityFallback {
|
||||
/**
|
||||
* Show the number as a single value rather than a range. Example: "$5"
|
||||
*
|
||||
@ -114,41 +128,64 @@ public abstract class NumberRangeFormatter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect
|
||||
* when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber.
|
||||
* Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range
|
||||
* were equal or not, and whether or not the identity fallback was applied.
|
||||
*
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
|
||||
public static enum RangeIdentityFallback {
|
||||
public static enum RangeIdentityType {
|
||||
/**
|
||||
* Show the number as a single value rather than a range. Example: "$5"
|
||||
* Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied.
|
||||
*
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
SINGLE_VALUE,
|
||||
EQUAL_BEFORE_ROUNDING,
|
||||
|
||||
/**
|
||||
* Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding,
|
||||
* show the single value. Example: "~$5" or "$5"
|
||||
* Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied.
|
||||
*
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
APPROXIMATELY_OR_SINGLE_VALUE,
|
||||
EQUAL_AFTER_ROUNDING,
|
||||
|
||||
/**
|
||||
* Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the
|
||||
* inputs are the same. Example: "~$5"
|
||||
* Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied.
|
||||
*
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
APPROXIMATELY,
|
||||
|
||||
/**
|
||||
* Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the
|
||||
* same. Example (with RangeCollapse.NONE): "$5 – $5"
|
||||
*/
|
||||
RANGE
|
||||
NOT_EQUAL
|
||||
}
|
||||
|
||||
private static final UnlocalizedNumberRangeFormatter BASE = new UnlocalizedNumberRangeFormatter();
|
||||
|
||||
/**
|
||||
* Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently
|
||||
* known at the call site.
|
||||
*
|
||||
* @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
|
||||
* @draft ICU 63
|
||||
*/
|
||||
public static UnlocalizedNumberRangeFormatter with() {
|
||||
return BASE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call
|
||||
* site.
|
||||
*
|
||||
* @param locale
|
||||
* The locale from which to load formats and symbols for number range formatting.
|
||||
* @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
|
||||
* @draft ICU 63
|
||||
*/
|
||||
public static LocalizedNumberRangeFormatter withLocale(Locale locale) {
|
||||
return BASE.locale(locale);
|
||||
}
|
||||
|
@ -53,19 +53,35 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
|
||||
* @see NumberFormatter
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
public T numberFormatter(UnlocalizedNumberFormatter formatter) {
|
||||
return numberFormatters(formatter, formatter);
|
||||
public T numberFormatterBoth(UnlocalizedNumberFormatter formatter) {
|
||||
return (T) numberFormatterFirst(formatter).numberFormatterSecond(formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the NumberFormatter instance to use for the first number in the range.
|
||||
* <p>
|
||||
* The NumberFormatter instance must not have a locale applied yet; the locale specified on the
|
||||
* NumberRangeFormatter will be used.
|
||||
*
|
||||
* @param formatterFirst
|
||||
* The formatter to use for the first number in the range.
|
||||
* @return The fluent chain.
|
||||
* @draft ICU 63
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
* @see NumberFormatter
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
public T numberFormatterFirst(UnlocalizedNumberFormatter formatterFirst) {
|
||||
return create(KEY_FORMATTER_1, formatterFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the NumberFormatter instances to use for the numbers in the range. This method allows you to set a different
|
||||
* formatter for the first and second numbers.
|
||||
* <p>
|
||||
* The NumberFormatter instances must not have a locale applied yet; the locale specified on the
|
||||
* The NumberFormatter instance must not have a locale applied yet; the locale specified on the
|
||||
* NumberRangeFormatter will be used.
|
||||
*
|
||||
* @param formatterFirst
|
||||
* The formatter to use for the first number in the range.
|
||||
* @param formatterSecond
|
||||
* The formatter to use for the second number in the range.
|
||||
* @return The fluent chain.
|
||||
@ -74,9 +90,8 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
|
||||
* @see NumberFormatter
|
||||
* @see NumberRangeFormatter
|
||||
*/
|
||||
public T numberFormatters(UnlocalizedNumberFormatter formatterFirst, UnlocalizedNumberFormatter formatterSecond) {
|
||||
T intermediate = create(KEY_FORMATTER_1, formatterFirst);
|
||||
return (T) intermediate.create(KEY_FORMATTER_2, formatterSecond);
|
||||
public T numberFormatterSecond(UnlocalizedNumberFormatter formatterSecond) {
|
||||
return create(KEY_FORMATTER_2, formatterSecond);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +128,7 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
|
||||
* <li>APPROXIMATELY: "~5 miles"</li>
|
||||
* <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
|
||||
* <p>
|
||||
* The default value is AUTO.
|
||||
* The default value is APPROXIMATELY.
|
||||
*
|
||||
* @param identityFallback
|
||||
* The strategy to use when formatting two numbers that end up being the same.
|
||||
|
@ -61,7 +61,7 @@ public class NumberRangeFormatterTest {
|
||||
public void testNullBehavior() {
|
||||
assertFormatRange(
|
||||
"Basic",
|
||||
NumberRangeFormatter.with().numberFormatter(null),
|
||||
NumberRangeFormatter.with().numberFormatterBoth(null),
|
||||
ULocale.US,
|
||||
"1 --- 5",
|
||||
"5 --- 5",
|
||||
@ -76,7 +76,7 @@ public class NumberRangeFormatterTest {
|
||||
|
||||
assertFormatRange(
|
||||
"Basic",
|
||||
NumberRangeFormatter.with().numberFormatters(null, null),
|
||||
NumberRangeFormatter.with().numberFormatterFirst(null),
|
||||
ULocale.US,
|
||||
"1 --- 5",
|
||||
"5 --- 5",
|
||||
@ -91,10 +91,9 @@ public class NumberRangeFormatterTest {
|
||||
|
||||
assertFormatRange(
|
||||
"Basic",
|
||||
NumberRangeFormatter.with().numberFormatters(
|
||||
NumberFormatter.with().grouping(GroupingStrategy.OFF),
|
||||
null
|
||||
),
|
||||
NumberRangeFormatter.with()
|
||||
.numberFormatterFirst(NumberFormatter.with().grouping(GroupingStrategy.OFF))
|
||||
.numberFormatterSecond(null),
|
||||
ULocale.US,
|
||||
"1 --- 5",
|
||||
"5 --- 5",
|
||||
@ -109,10 +108,9 @@ public class NumberRangeFormatterTest {
|
||||
|
||||
assertFormatRange(
|
||||
"Basic",
|
||||
NumberRangeFormatter.with().numberFormatters(
|
||||
null,
|
||||
NumberFormatter.with().grouping(GroupingStrategy.OFF)
|
||||
),
|
||||
NumberRangeFormatter.with()
|
||||
.numberFormatterFirst(null)
|
||||
.numberFormatterSecond(NumberFormatter.with().grouping(GroupingStrategy.OFF)),
|
||||
ULocale.US,
|
||||
"1 --- 5",
|
||||
"5 --- 5",
|
||||
|
Loading…
Reference in New Issue
Block a user