mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-22781 Fix &Improve MeasureUnit identifier generation for constant denominators (Java)
See #3363
This commit is contained in:
parent
a262e87aa6
commit
bc7ccb0589
2 changed files with 71 additions and 3 deletions
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue