From fc0e6258dbee3d10ff52e4573ecfdee951669d2b Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Tue, 28 Aug 2018 21:10:28 -0700 Subject: [PATCH] ICU-11276 Adding enums and more API docs. --- .../number/LocalizedNumberRangeFormatter.java | 15 ++- .../ibm/icu/number/NumberRangeFormatter.java | 127 +++++++++++++++++- .../number/NumberRangeFormatterSettings.java | 71 ++++++++++ 3 files changed, 206 insertions(+), 7 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java index 87d94941bb0..193706b3a96 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java @@ -38,7 +38,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< public FormattedNumberRange formatRange(int first, int second) { DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first); DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second); - return formatImpl(dq1, dq2); + return formatImpl(dq1, dq2, first == second); } /** @@ -57,7 +57,9 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< public FormattedNumberRange formatRange(double first, double second) { DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first); DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second); - return formatImpl(dq1, dq2); + // Note: double equality could be changed to epsilon equality later if there is demand. + // The epsilon should be set via an API method. + return formatImpl(dq1, dq2, first == second); } /** @@ -74,12 +76,15 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< * @see NumberRangeFormatter */ public FormattedNumberRange formatRange(Number first, Number second) { + if (first == null || second == null) { + throw new IllegalArgumentException("Cannot format null values in range"); + } DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first); DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second); - return formatImpl(dq1, dq2); + return formatImpl(dq1, dq2, first.equals(second)); } - FormattedNumberRange formatImpl(DecimalQuantity first, DecimalQuantity second) { + FormattedNumberRange formatImpl(DecimalQuantity first, DecimalQuantity second, boolean equalBeforeRounding) { // TODO: This is a placeholder implementation. RangeMacroProps macros = resolve(); LocalizedNumberFormatter f1 , f2; @@ -99,7 +104,7 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings< nsb.append(r1.nsb); nsb.append(" --- ", null); nsb.append(r2.nsb); - RangeIdentityType identityType = (first == second) ? RangeIdentityType.EQUAL_BEFORE_ROUNDING + RangeIdentityType identityType = equalBeforeRounding ? RangeIdentityType.EQUAL_BEFORE_ROUNDING : RangeIdentityType.NOT_EQUAL; return new FormattedNumberRange(nsb, first, second, identityType); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java index da6618b5626..a138a6d2daf 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java @@ -16,9 +16,132 @@ import com.ibm.icu.util.ULocale; */ public abstract class NumberRangeFormatter { - public static enum RangeCollapse {} + /** + * Defines how to merge fields that are identical across the range sign. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + public enum RangeCollapse { + /** + * Use locale data and heuristics to determine how much of the string to collapse. Could end up collapsing none, + * some, or all repeated pieces in a locale-sensitive way. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + AUTO, - public static enum RangeIdentityFallback {} + /** + * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + NONE, + + /** + * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand + * kilograms" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + UNIT, + + /** + * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the + * number. Example: "3.2 – 5.3 thousand kilograms" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + ALL + } + + /** + * 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. + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + public enum IdentityFallback { + /** + * Show the number as a single value rather than a range. Example: "$5" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + SINGLE_VALUE, + + /** + * 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" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + APPROXIMATELY_OR_SINGLE_VALUE, + + /** + * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the + * inputs are the same. Example: "~$5" + * + * @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" + * + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @see NumberRangeFormatter + */ + RANGE + } + + /** + * 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. + */ + + public static enum RangeIdentityFallback { + /** + * Show the number as a single value rather than a range. Example: "$5" + */ + SINGLE_VALUE, + + /** + * 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" + */ + APPROXIMATELY_OR_SINGLE_VALUE, + + /** + * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the + * inputs are the same. Example: "~$5" + */ + 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 + } private static final UnlocalizedNumberRangeFormatter BASE = new UnlocalizedNumberRangeFormatter(); diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java index 23de02a0716..7c9a70fb23b 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java @@ -38,19 +38,90 @@ public abstract class NumberRangeFormatterSettings + * The NumberFormatter instances must not have a locale applied yet; the locale specified on the + * NumberRangeFormatter will be used. + * + * @param formatter + * The formatter to use for both numbers 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 numberFormatter(UnlocalizedNumberFormatter formatter) { return numberFormatters(formatter, formatter); } + /** + * 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. + *

+ * The NumberFormatter instances 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. + * @draft ICU 63 + * @provisional This API might change or be removed in a future release. + * @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); } + /** + * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values: + *

+ *