]> granicus.if.org Git - icu/commitdiff
ICU-21765 Add approximately sign field
authorShane F. Carr <shane@unicode.org>
Tue, 22 Feb 2022 20:58:37 +0000 (20:58 +0000)
committerShane F. Carr <shane@unicode.org>
Wed, 23 Feb 2022 17:38:42 +0000 (10:38 -0700)
See #1978

icu4c/source/i18n/number_affixutils.cpp
icu4c/source/i18n/unicode/unum.h
icu4c/source/test/intltest/numbertest_range.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/number/AffixUtils.java
icu4j/main/classes/core/src/com/ibm/icu/text/NumberFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java

index f9c154c885cd8aed375ff13d9275b4e87c6a490f..5f5ff4c3a6342273033eed0eb32d0ff52451f4db 100644 (file)
@@ -135,8 +135,7 @@ Field AffixUtils::getFieldForType(AffixPatternType type) {
         case TYPE_PLUS_SIGN:
             return {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD};
         case TYPE_APPROXIMATELY_SIGN:
-            // TODO: Introduce a new field for the approximately sign?
-            return {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD};
+            return {UFIELD_CATEGORY_NUMBER, UNUM_APPROXIMATELY_SIGN_FIELD};
         case TYPE_PERCENT:
             return {UFIELD_CATEGORY_NUMBER, UNUM_PERCENT_FIELD};
         case TYPE_PERMILLE:
index 14f76168b61b5fa74ca2d9c29151252bd57ccf48..c830d2da4057ad3e3d1871ced11e7617dc2c221e 100644 (file)
@@ -401,13 +401,24 @@ typedef enum UNumberFormatFields {
     UNUM_MEASURE_UNIT_FIELD,
     /** @stable ICU 64 */
     UNUM_COMPACT_FIELD,
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * Approximately sign. In ICU 70, this was categorized under the generic SIGN field.
+     * @draft ICU 71
+     */
+    UNUM_APPROXIMATELY_SIGN_FIELD,
+#endif // U_HIDE_DRAFT_API
 
 #ifndef U_HIDE_DEPRECATED_API
     /**
      * One more than the highest normal UNumberFormatFields value.
      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
      */
-    UNUM_FIELD_COUNT = UNUM_SIGN_FIELD + 3
+#ifndef U_HIDE_DRAFT_API
+    UNUM_FIELD_COUNT = UNUM_COMPACT_FIELD + 2
+#else  // U_HIDE_DRAFT_API (for UNUM_APPROXIMATELY_SIGN_FIELD)
+    UNUM_FIELD_COUNT = UNUM_COMPACT_FIELD + 1
+#endif  // U_HIDE_DRAFT_API (for UNUM_APPROXIMATELY_SIGN_FIELD)
 #endif  /* U_HIDE_DEPRECATED_API */
 } UNumberFormatFields;
 
index 08e74df8f528ccdacfcc15fd9d0d85f43fb90808..a47c675c97489dbde147668266e68d77ec22aa97 100644 (file)
@@ -811,6 +811,28 @@ void NumberRangeFormatterTest::testFieldPositions() {
             expectedFieldPositions,
             UPRV_LENGTHOF(expectedFieldPositions));
     }
+
+    {
+        const char16_t* message = u"Field position with approximately sign";
+        const char16_t* expectedString = u"~-100";
+        FormattedNumberRange result = assertFormattedRangeEquals(
+            message,
+            NumberRangeFormatter::withLocale("en-us"),
+            -100,
+            -100,
+            expectedString);
+        static const UFieldPositionWithCategory expectedFieldPositions[] = {
+            // category, field, begin index, end index
+            {UFIELD_CATEGORY_NUMBER, UNUM_APPROXIMATELY_SIGN_FIELD, 0, 1},
+            {UFIELD_CATEGORY_NUMBER, UNUM_SIGN_FIELD, 1, 2},
+            {UFIELD_CATEGORY_NUMBER, UNUM_INTEGER_FIELD, 2, 5}};
+        checkMixedFormattedValue(
+            message,
+            result,
+            expectedString,
+            expectedFieldPositions,
+            UPRV_LENGTHOF(expectedFieldPositions));
+    }
 }
 
 void NumberRangeFormatterTest::testCopyMove() {
index 8f9a575ea4fe8a5e6e3eb7f08b0af4397f7b5520..2430999d387e426e7d0a46ca4c5ee16d46d54af9 100644 (file)
@@ -271,8 +271,7 @@ public class AffixUtils {
         case TYPE_PLUS_SIGN:
             return NumberFormat.Field.SIGN;
         case TYPE_APPROXIMATELY_SIGN:
-            // TODO: Introduce a new field for the approximately sign?
-            return NumberFormat.Field.SIGN;
+            return NumberFormat.Field.APPROXIMATELY_SIGN;
         case TYPE_PERCENT:
             return NumberFormat.Field.PERCENT;
         case TYPE_PERMILLE:
index f23552c0a3a5ea2b6d215c8b1c84bfce644d9d70..b9ba1d9a5857c659443a385c0aa2e4394df118b5 100644 (file)
@@ -1969,6 +1969,12 @@ public abstract class NumberFormat extends UFormat {
          */
         public static final Field COMPACT = new Field("compact");
 
+        /**
+         * Approximately sign. In ICU 70, this was categorized under the generic SIGN field.
+         * @draft ICU 71
+         */
+        public static final Field APPROXIMATELY_SIGN = new Field("approximately sign");
+
         /**
          * Constructs a new instance of NumberFormat.Field with the given field
          * name.
index c87a804690b43e7cb24532eafc52da6d0be0a419..f636c84472120d595aa82edc58aa8c04682de651 100644 (file)
@@ -693,7 +693,7 @@ public class NumberRangeFormatterTest extends TestFmwk {
         FormattedNumberRange result4 = lnf.formatRange(Double.NaN, 0);
         FormattedNumberRange result5 = lnf.formatRange(0, Double.NaN);
         FormattedNumberRange result6 = lnf.formatRange(Double.NaN, Double.NaN);
-    
+
         assertEquals("0 - inf", "-∞ – 0", result1.toString());
         assertEquals("-inf - 0", "0–∞", result2.toString());
         assertEquals("-inf - inf", "-∞ – ∞", result3.toString());
@@ -804,6 +804,22 @@ public class NumberRangeFormatterTest extends TestFmwk {
                     {NumberFormat.Field.INTEGER, 11, 21}};
             FormattedValueTest.checkFormattedValue(message, fmtd, expectedString, expectedFieldPositions);
         }
+
+        {
+            String message = "Field position with approximately sign";
+            String expectedString = "~-100";
+            FormattedNumberRange fmtd = assertFormattedRangeEquals(
+                    message,
+                    NumberRangeFormatter.withLocale(ULocale.US),
+                    -100,
+                    -100,
+                    expectedString);
+            Object[][] expectedFieldPositions = new Object[][]{
+                    {NumberFormat.Field.APPROXIMATELY_SIGN, 0, 1},
+                    {NumberFormat.Field.SIGN, 1, 2},
+                    {NumberFormat.Field.INTEGER, 2, 5}};
+            FormattedValueTest.checkFormattedValue(message, fmtd, expectedString, expectedFieldPositions);
+        }
     }
 
     static final String[] allNSNames = NumberingSystem.getAvailableNames();
@@ -899,7 +915,7 @@ public class NumberRangeFormatterTest extends TestFmwk {
             "CHF 4’999.00–5’001.00",
             "CHF≈5’000.00",
             "CHF 5’000.00–5’000’000.00");
-    
+
         // TODO(CLDR-13044): Move the sign to the inside of the number
         assertFormatRange(
             "Approximately sign position with currency spacing",
@@ -916,14 +932,14 @@ public class NumberRangeFormatterTest extends TestFmwk {
             "CHF 4,999.00–5,001.00",
             "~CHF 5,000.00",
             "CHF 5,000.00–5,000,000.00");
-    
+
         {
             LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
                 .withLocale(ULocale.forLanguageTag("de-CH"));
             String actual = lnrf.formatRange(-2, 3).toString();
             assertEquals("Negative to positive range", "-2 – 3", actual);
         }
-    
+
         {
             LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
                 .withLocale(ULocale.forLanguageTag("de-CH"))
@@ -931,7 +947,7 @@ public class NumberRangeFormatterTest extends TestFmwk {
             String actual = lnrf.formatRange(-2, 3).toString();
             assertEquals("Negative to positive percent", "-2% – 3%", actual);
         }
-    
+
         {
             // TODO(CLDR-14111): Add spacing between range separator and sign
             LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
@@ -939,7 +955,7 @@ public class NumberRangeFormatterTest extends TestFmwk {
             String actual = lnrf.formatRange(2, -3).toString();
             assertEquals("Positive to negative range", "2–-3", actual);
         }
-    
+
         {
             LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter
                 .withLocale(ULocale.forLanguageTag("de-CH"))