diff --git a/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/format/MeasureUnitTest.java b/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/format/MeasureUnitTest.java index 5be097507d6..c840c20291c 100644 --- a/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/format/MeasureUnitTest.java +++ b/icu4j/main/common_tests/src/test/java/com/ibm/icu/dev/test/format/MeasureUnitTest.java @@ -1455,6 +1455,32 @@ public class MeasureUnitTest extends CoreTestFmwk { } } + @Test + public void TestGetIdentifierForConstantDenominator() { + String testCases[][] = { + { "meter-per-1000", "meter-per-1000" }, + { "meter-per-1000-kilometer", "meter-per-1000-kilometer" }, + { "meter-per-1000000", "meter-per-1e6" }, + { "meter-per-1000000-kilometer", "meter-per-1e6-kilometer" }, + { "meter-per-1000000000", "meter-per-1e9" }, + { "meter-per-1000000000-kilometer", "meter-per-1e9-kilometer" }, + { "meter-per-1000000000000", "meter-per-1e12" }, + { "meter-per-1000000000000-kilometer", "meter-per-1e12-kilometer" }, + { "meter-per-1000000000000000", "meter-per-1e15" }, + { "meter-per-1e15-kilometer", "meter-per-1e15-kilometer" }, + { "meter-per-1000000000000000000", "meter-per-1e18" }, + { "meter-per-1e18-kilometer", "meter-per-1e18-kilometer" }, + { "meter-per-1000000000000001", "meter-per-1000000000000001" }, + { "meter-per-1000000000000001-kilometer", "meter-per-1000000000000001-kilometer" }, + }; + + for (String[] testCase : testCases) { + MeasureUnit unit = MeasureUnit.forIdentifier(testCase[0]); + String actual = unit.getIdentifier(); + assertEquals(testCase[0], testCase[1], actual); + } + } + @Test public void TestIdentifierDetails() { MeasureUnit joule = MeasureUnit.forIdentifier("joule"); diff --git a/icu4j/main/core/src/main/java/com/ibm/icu/impl/units/MeasureUnitImpl.java b/icu4j/main/core/src/main/java/com/ibm/icu/impl/units/MeasureUnitImpl.java index e42797f2016..9ae09bebd95 100644 --- a/icu4j/main/core/src/main/java/com/ibm/icu/impl/units/MeasureUnitImpl.java +++ b/icu4j/main/core/src/main/java/com/ibm/icu/impl/units/MeasureUnitImpl.java @@ -256,6 +256,46 @@ public class MeasureUnitImpl { this.constantDenominator = constantDenominator; } + private int countCharacter(String str, char ch) { + int count = 0; + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == ch) { + count++; + } + } + return count; + } + + /** + * Internal function that returns a string of the constants in the correct + * format. + * + * Example: + * 1000 --> "-per-1000" + * 1000000 --> "-per-1e6" + * + * NOTE: this function is only used when the constant denominator is greater + * than 0. + */ + private String getConstantsString(long constantDenominator) { + assert constantDenominator > 0; + StringBuilder constantString = new StringBuilder(); + constantString.append(constantDenominator); + String result = constantString.toString(); + + if (constantDenominator <= 1000) { + return result; + } + + // Check if the constant denominator is a power of 10 + int zeroCount = countCharacter(result, '0'); + if (zeroCount == result.length() - 1 && result.charAt(0) == '1') { + return "1e" + zeroCount; + } + + return result; + } + /** * Normalizes the MeasureUnitImpl and generates the identifier string in place. */ @@ -274,6 +314,7 @@ public class MeasureUnitImpl { StringBuilder result = new StringBuilder(); boolean beforePer = true; boolean firstTimeNegativeDimension = false; + boolean isConstantDenominatorAdded = false; for (SingleUnitImpl singleUnit : this.getSingleUnits()) { if (beforePer && singleUnit.getDimensionality() < 0) { beforePer = false; @@ -284,8 +325,9 @@ public class MeasureUnitImpl { if (firstTimeNegativeDimension && this.constantDenominator > 0) { result.append("-per-"); - result.append(this.constantDenominator); + result.append(getConstantsString(this.constantDenominator)); firstTimeNegativeDimension = false; + isConstantDenominatorAdded = true; } if (this.getComplexity() == MeasureUnit.Complexity.MIXED) { @@ -309,9 +351,9 @@ public class MeasureUnitImpl { result.append(singleUnit.getNeutralIdentifier()); } - if (this.constantDenominator > 0) { + if (this.constantDenominator > 0 && !isConstantDenominatorAdded) { result.append("-per-"); - result.append(this.constantDenominator); + result.append(getConstantsString(this.constantDenominator)); } this.identifier = result.toString();