]> granicus.if.org Git - icu/commitdiff
finish unit converter library
authorYounies <younies.mahmoud@gmail.com>
Fri, 21 Feb 2020 17:33:15 +0000 (18:33 +0100)
committerYounies <younies.mahmoud@gmail.com>
Fri, 21 Feb 2020 17:33:15 +0000 (18:33 +0100)
icu4c/source/i18n/unitconverter.cpp
icu4c/source/i18n/unitconverter.h
icu4c/source/test/intltest/unitstest.cpp

index e5e8a181c71dddf9afd4c36d2446d06efbbc830b..f48a2a993cc6aee0f63831e589c8255b30e9dbdf 100644 (file)
@@ -44,14 +44,17 @@ struct Factor {
         factorDen.multiplyBy(rhs.factorDen, status);
         for (int i = 0; i < CONSTANTS_COUNT; i++)
             constants[i] += rhs.constants[i];
-        offset.add(rhs.offset, status); // TODO(younies): fix this.
+
+        offset.add(rhs.offset, status);
     }
 
     void divideBy(const Factor &rhs, UErrorCode &status) {
         factorNum.multiplyBy(rhs.factorDen, status);
         factorDen.multiplyBy(rhs.factorNum, status);
         for (int i = 0; i < CONSTANTS_COUNT; i++)
-            constants[i] -= rhs.constants[i]; // TODO(younies): fix this
+            constants[i] -= rhs.constants[i];
+
+        offset.add(rhs.offset, status);
     }
 
     // apply the power to the factor.
@@ -154,14 +157,14 @@ void addSingleFactorConstant(Factor &factor, StringPiece baseStr, number::impl::
         factor.constants[CONSTANT_LB2KG] += power.toInt32();
     } else if (baseStr == "cup2m3") {
         factor.constants[CONSTANT_CUP2M3] += power.toInt32();
-    } else if (baseStr == "pi") {
+    } else if (baseStr == "PI") {
         factor.constants[CONSTANT_PI] += power.toInt32();
     } else {
         if (U_FAILURE(status)) return;
 
         number::impl::DecNum factorNumber;
-        factorNumber.setTo(baseStr.data(), status);
-
+        factorNumber.setTo(baseStr, status);
+        // TODO(younies): do not use the signal, use the power.
         if (signal < 0) { // negative number means add the factor to the denominator.
             factor.factorDen.multiplyBy(factorNumber, status);
         } else {
@@ -219,7 +222,8 @@ void extractFactor(Factor &factor, StringPiece stringFactor, UErrorCode &status)
     auto factorData = stringFactor.data();
     for (int32_t i = 0, start = 0, n = stringFactor.length(); i < n; i++) {
         if (factorData[i] == '*' || factorData[i] == '/') {
-            addFactorElement(factor, stringFactor.substr(start, i), signal, status);
+            StringPiece factorElement = stringFactor.substr(start, i - start);
+            addFactorElement(factor, factorElement, signal, status);
 
             start = i + 1; // Set `start` to point to the start of the new element.
         } else if (i == n - 1) {
@@ -264,7 +268,7 @@ void loadCompoundFactor(Factor &factor, StringPiece source, UErrorCode &status)
         singleFactor.applySiPrefix(singleUnit.siPrefix, status);
 
         singleFactor.power(singleUnit.dimensionality, status);
-        
+
         factor.multiplyBy(singleFactor, status);
     }
 }
@@ -291,7 +295,7 @@ void substituteConstants(Factor &factor, UErrorCode &status) {
     DecNum constSubs[CONSTANTS_COUNT];
 
     constSubs[CONSTANT_FT2M].setTo(0.3048, status);
-    constSubs[CONSTANT_PI].setTo(3.142, status);
+    constSubs[CONSTANT_PI].setTo(3.14159265359, status);
     constSubs[CONSTANT_GRAVITY].setTo(9.80665, status);
     constSubs[CONSTANT_G].setTo("0.0000000000667408", status);
     constSubs[CONSTANT_CUP2M3].setTo("0.000236588", status);
@@ -304,6 +308,23 @@ void substituteConstants(Factor &factor, UErrorCode &status) {
     }
 }
 
+/**
+ * Checks if the source unit and the target unit are singular. For example celsius or fahrenheit. But not
+ * square-celsius or square-fahrenheit.
+ */
+UBool checkSingularUnits(StringPiece source, UErrorCode &status) {
+    icu::MeasureUnit compoundSourceUnit = icu::MeasureUnit::forIdentifier(source, status);
+
+    auto singleUnits = compoundSourceUnit.splitToSingleUnits(status);
+    if (singleUnits.length() > 1) return false; // Singular unit contains only a single unit.
+
+    auto singleUnit = TempSingleUnit::forMeasureUnit(singleUnits[0], status);
+
+    if (singleUnit.dimensionality != 1) return false;
+    if (singleUnit.siPrefix == UMeasureSIPrefix::UMEASURE_SI_PREFIX_ONE) return true;
+    return false;
+}
+
 /**
  *  Extract conversion rate from `source` to `target`
  */
@@ -347,7 +368,18 @@ void loadConversionRate(ConversionRate &conversionRate, StringPiece source, Stri
     conversionRate.factorNum.setTo(finalFactor.factorNum, status);
     conversionRate.factorDen.setTo(finalFactor.factorDen, status);
 
-    conversionRate.offset.setTo(finalFactor.offset, status);
+    if (checkSingularUnits(source, status) && checkSingularUnits(target, status)) {
+
+        double num1 = SourcetoMiddle.factorNum.toDouble();
+        double den1 = SourcetoMiddle.factorDen.toDouble();
+        double newOffset1 = SourcetoMiddle.offset.toDouble() * den1 / num1;
+        conversionRate.sourceOffset.setTo(newOffset1, status);
+
+        double num2 = TargettoMiddle.factorNum.toDouble();
+        double den2 = TargettoMiddle.factorDen.toDouble();
+        double newOffset2 = TargettoMiddle.offset.toDouble() * den2 / num2;
+        conversionRate.targetOffset.setTo(newOffset2, status);
+    }
 
     // TODO(younies): use the database.
     // UnitConversionRatesSink sink(&conversionFactor);
@@ -390,11 +422,13 @@ void UnitConverter::convert(const DecNum &input_value, DecNum &output_value, UEr
         output_value.setTo(result, status);
     }*/
 
-    double result = input_value.toDouble();
+    double result = input_value.toDouble() + conversion_rate_.sourceOffset.toDouble();
     double num = conversion_rate_.factorNum.toDouble();
     double den = conversion_rate_.factorDen.toDouble();
     result *= num / den;
 
+    result -= conversion_rate_.targetOffset.toDouble();
+
     output_value.setTo(result, status);
 }
 
index 738e1811c5176dff1be5118019f450ac2760f851..1ca89c566ccb1eeccedb3ad4fcc44f46feb199d3 100644 (file)
@@ -36,13 +36,15 @@ struct ConversionRate {
     StringPiece target;
     number::impl::DecNum factorNum;
     number::impl::DecNum factorDen;
-    number::impl::DecNum offset;
+    number::impl::DecNum sourceOffset;
+    number::impl::DecNum targetOffset;
     bool reciprocal;
 
     ConversionRate(UErrorCode &status) {
         factorNum.setTo(1.0, status);
         factorDen.setTo(1.0, status);
-        offset.setTo(0.0, status);
+        sourceOffset.setTo(0.0, status);
+        targetOffset.setTo(0.0, status);        
         reciprocal = false;
     }
 };
@@ -119,7 +121,7 @@ struct entry {
     {"horsepower", "kilogram-square-meter-per-cubic-second", "ft2m*lb2kg*gravity*550", "0", false},
     {"inch-hg", "kilogram-per-meter-square-second", "3386.389", "0", false},
     {"knot", "meter-per-second", "1852/3600", "0", false},
-    {"fahrenheit", "kelvin", "5/9", "2298.35/9", false},
+    {"fahrenheit", "kelvin", "5/9", "255.372222222", false}, //2298.35/9
     {"barrel", "cubic-meter", "cup2m3*672", "0", false},
     {"bushel", "cubic-meter", "0.03523907", "0", false},
     {"cup", "cubic-meter", "cup2m3", "0", false},
@@ -143,7 +145,7 @@ struct entry {
     {"watt", "kilogram-square-meter-per-cubic-second", "1", "0", false},
     {"bar", "kilogram-per-meter-square-second", "100000", "0", false},
     {"pascal", "kilogram-per-meter-square-second", "1", "0", false},
-    {"celsius", "kelvin", "1", "-273.15", false},
+    {"celsius", "kelvin", "1", "273.15", false},
     {"cup-metric", "cubic-meter", "0.00025", "0", false},
     {"liter", "cubic-meter", "0.001", "0", false},
     {"pint-metric", "cubic-meter", "0.0005", "0", false},
index 21c1088a12a0479e27e3d89a767e40d4b11e2e4c..638d67c6412b2c84b27c57e8229fe3e6cd671f7a 100644 (file)
@@ -28,6 +28,8 @@ class UnitsTest : public IntlTest {
     void testTemperature();
     void testArea();
     void testComplicatedUnits();
+    void testCLDRUnitsTests();
+    void testCLDRUnitsTests2();
 
     // TODO(younies): fix this.
     void verifyTestCase(const UnitConversionTestCase &testCase);
@@ -39,6 +41,7 @@ void UnitsTest::runIndexedTest(int32_t index, UBool exec, const char *&name, cha
     if (exec) {
         logln("TestSuite UnitsTest: ");
     }
+
     TESTCASE_AUTO_BEGIN;
     TESTCASE_AUTO(testBasic);
     TESTCASE_AUTO(testSiPrefixes);
@@ -46,6 +49,8 @@ void UnitsTest::runIndexedTest(int32_t index, UBool exec, const char *&name, cha
     TESTCASE_AUTO(testTemperature);
     TESTCASE_AUTO(testArea);
     TESTCASE_AUTO(testComplicatedUnits);
+    TESTCASE_AUTO(testCLDRUnitsTests);
+    TESTCASE_AUTO(testCLDRUnitsTests2);
     TESTCASE_AUTO_END;
 }
 
@@ -182,10 +187,10 @@ void UnitsTest::testArea() {
 }
 
 void UnitsTest::testComplicatedUnits() {
-        IcuTestErrorCode status(*this, "Units Area");
+    IcuTestErrorCode status(*this, "Units Area");
 
     UnitConversionTestCase testCases[]{
-        {"meter-per-second", "meter-per-millisecond", 1000.0, 1.0} //
+        {"meter-per-second", "meter-per-square-millisecond", 1000000.0, 1.0} //
     };
 
     for (const auto &testCase : testCases) {
@@ -193,4 +198,243 @@ void UnitsTest::testComplicatedUnits() {
     }
 }
 
+void UnitsTest::testCLDRUnitsTests() {
+    struct {
+        const StringPiece category;
+        const StringPiece source;
+        const StringPiece target;
+        const StringPiece inputValue;
+        const StringPiece expectedValue;
+    } testCases[]{
+        {"acceleration", "meter-per-square-second", "meter-per-square-second", "1000", "1000.0"},
+        {"acceleration", "g-force", "meter-per-square-second", "1000", "9806.65"},
+        {"angle", "arc-second", "revolution", "1000", "0.0007716049"},
+        {"angle", "arc-minute", "revolution", "1000", "0.0462963"},
+        {"angle", "degree", "revolution", "1000", "2.777778"},
+        {"angle", "radian", "revolution", "1000", "159.1549"},
+        {"angle", "revolution", "revolution", "1000", "1000.0"},
+        {"area", "square-centimeter", "square-meter", "1000", "0.1"},
+        {"area", "square-inch", "square-meter", "1000", "0.64516"},
+        {"area", "square-foot", "square-meter", "1000", "92.90304"},
+        {"area", "square-yard", "square-meter", "1000", "836.1274"},
+        {"area", "square-meter", "square-meter", "1000", "1000.0"},
+        {"area", "dunam", "square-meter", "1000", "1000000.0"},
+        {"area", "acre", "square-meter", "1000", "4046856.0"},
+        {"area", "hectare", "square-meter", "1000", "10000000.0"},
+        {"area", "square-kilometer", "square-meter", "1000", "1000000000.0"},
+        {"area", "square-mile", "square-meter", "1000", "2589988000.0"},
+        {"concentration", "millimole-per-liter", "item-per-cubic-meter", "1000", "6.022141e+26"},
+        {"consumption", "liter-per-100-kilometer", "cubic-meter-per-meter", "1000", "1e-05"},
+        {"consumption", "liter-per-kilometer", "cubic-meter-per-meter", "1000", "0.001"},
+        {"consumption-inverse", "mile-per-gallon-imperial", "meter-per-cubic-meter", "1000",
+         "354006200.0"},
+        {"consumption-inverse", "mile-per-gallon", "meter-per-cubic-meter", "1000", "425143700.0"},
+        {"digital", "bit", "bit", "1000", "1000.0"},
+        {"digital", "byte", "bit", "1000", "8000.0"},
+        {"digital", "kilobit", "bit", "1000", "1000000.0"},
+        {"digital", "kilobyte", "bit", "1000", "8000000.0"},
+        {"digital", "megabit", "bit", "1000", "1000000000.0"},
+        {"digital", "megabyte", "bit", "1000", "8000000000.0"},
+        {"digital", "gigabit", "bit", "1000", "1e+12"},
+        {"digital", "gigabyte", "bit", "1000", "8e+12"},
+        {"digital", "terabit", "bit", "1000", "1e+15"},
+        {"digital", "terabyte", "bit", "1000", "8e+15"},
+        {"digital", "petabyte", "bit", "1000", "8e+18"},
+        {"duration", "nanosecond", "second", "1000", "1e-06"},
+        {"duration", "microsecond", "second", "1000", "0.001"},
+        {"duration", "millisecond", "second", "1000", "1.0"},
+        {"duration", "second", "second", "1000", "1000.0"},
+        {"duration", "minute", "second", "1000", "60000.0"},
+        {"duration", "hour", "second", "1000", "3600000.0"},
+        {"duration", "day", "second", "1000", "86400000.0"},
+        {"duration", "day-person", "second", "1000", "86400000.0"},
+        {"duration", "week", "second", "1000", "604800000.0"},
+        {"duration", "week-person", "second", "1000", "604800000.0"},
+        {"electric-current", "milliampere", "ampere", "1000", "1.0"},
+        {"electric-current", "ampere", "ampere", "1000", "1000.0"},
+        {"electric-resistance", "ohm", "kilogram-square-meter-per-cubic-second-square-ampere", "1000",
+         "1000.0"},
+        {"energy", "electronvolt", "kilogram-square-meter-per-square-second", "1000", "1.602177e-16"},
+        {"energy", "dalton", "kilogram-square-meter-per-square-second", "1000", "1.492418e-07"},
+        {"energy", "joule", "kilogram-square-meter-per-square-second", "1000", "1000.0"},
+        {"energy", "newton-meter", "kilogram-square-meter-per-square-second", "1000", "1000.0"},
+        {"energy", "pound-force-foot", "kilogram-square-meter-per-square-second", "1000", "1355.818"},
+        {"energy", "calorie", "kilogram-square-meter-per-square-second", "1000", "4184.0"},
+        {"energy", "kilojoule", "kilogram-square-meter-per-square-second", "1000", "1000000.0"},
+        {"energy", "british-thermal-unit", "kilogram-square-meter-per-square-second", "1000",
+         "1055060.0"},
+        {"energy", "foodcalorie", "kilogram-square-meter-per-square-second", "1000", "4184000.0"},
+        {"energy", "kilocalorie", "kilogram-square-meter-per-square-second", "1000", "4184000.0"},
+        {"energy", "kilowatt-hour", "kilogram-square-meter-second-per-cubic-second", "1000",
+         "3600000000.0"},
+        {"energy", "therm-us", "kilogram-square-meter-per-square-second", "1000", "1.05506e+11"},
+        {"force", "newton", "kilogram-meter-per-square-second", "1000", "1000.0"},
+        {"force", "pound-force", "kilogram-meter-per-square-second", "1000", "4448.222"},
+        {"frequency", "hertz", "revolution-per-second", "1000", "1000.0"},
+        {"frequency", "kilohertz", "revolution-per-second", "1000", "1000000.0"},
+        {"frequency", "megahertz", "revolution-per-second", "1000", "1000000000.0"},
+        {"frequency", "gigahertz", "revolution-per-second", "1000", "1e+12"},
+        {"graphics", "pixel", "pixel", "1000", "1000.0"},
+        {"graphics", "megapixel", "pixel", "1000", "1000000000.0"},
+        {"length", "picometer", "meter", "1000", "1e-09"},
+        {"length", "nanometer", "meter", "1000", "1e-06"},
+        {"length", "micrometer", "meter", "1000", "0.001"},
+        {"length", "point", "meter", "1000", "0.3527778"},
+        {"length", "millimeter", "meter", "1000", "1.0"},
+        {"length", "centimeter", "meter", "1000", "10.0"},
+        {"length", "inch", "meter", "1000", "25.4"},
+        {"length", "decimeter", "meter", "1000", "100.0"},
+        {"length", "foot", "meter", "1000", "304.8"},
+        {"length", "yard", "meter", "1000", "914.4"},
+        {"length", "meter", "meter", "1000", "1000.0"},
+        {"length", "fathom", "meter", "1000", "1828.8"},
+        {"length", "furlong", "meter", "1000", "201168.0"},
+        {"length", "kilometer", "meter", "1000", "1000000.0"},
+        {"length", "mile", "meter", "1000", "1609344.0"},
+        {"length", "nautical-mile", "meter", "1000", "1852000.0"},
+        {"length", "mile-scandinavian", "meter", "1000", "10000000.0"},
+        {"length", "solar-radius", "meter", "1000", "6.957e+11"},
+        {"length", "astronomical-unit", "meter", "1000", "1.495979e+14"},
+        {"length", "light-year", "meter", "1000", "9.46073e+18"},
+        {"length", "parsec", "meter", "1000", "3.085678e+19"},
+        {"luminous-flux", "lux", "candela-square-meter-per-square-meter", "1000", "1000.0"},
+        {"mass", "microgram", "kilogram", "1000", "1e-06"},
+        {"mass", "milligram", "kilogram", "1000", "0.001"},
+        {"mass", "carat", "kilogram", "1000", "0.2"},
+        {"mass", "gram", "kilogram", "1000", "1.0"},
+        {"mass", "ounce", "kilogram", "1000", "28.34952"},
+        {"mass", "ounce-troy", "kilogram", "1000", "31.10348"},
+        {"mass", "pound", "kilogram", "1000", "453.5924"},
+        {"mass", "kilogram", "kilogram", "1000", "1000.0"},
+        {"mass", "stone", "kilogram", "1000", "6350.293"},
+        {"mass", "ton", "kilogram", "1000", "907184.7"},
+        {"mass", "metric-ton", "kilogram", "1000", "1000000.0"},
+        {"mass", "earth-mass", "kilogram", "1000", "5.9722e+27"},
+        {"mass", "solar-mass", "kilogram", "1000", "1.98847e+33"},
+        {"mass-density", "milligram-per-deciliter", "kilogram-per-cubic-meter", "1000", "10.0"},
+        {"portion", "part-per-million", "portion", "1000", "0.001"},
+        {"portion", "permyriad", "portion", "1000", "0.1"},
+        {"portion", "permille", "portion", "1000", "1.0"},
+        {"portion", "percent", "portion", "1000", "10.0"},
+        {"portion", "karat", "portion", "1000", "41.66667"},
+        {"power", "milliwatt", "kilogram-square-meter-per-cubic-second", "1000", "1.0"},
+        {"power", "watt", "kilogram-square-meter-per-cubic-second", "1000", "1000.0"},
+        {"power", "horsepower", "kilogram-square-meter-per-cubic-second", "1000", "745699.9"},
+        {"power", "kilowatt", "kilogram-square-meter-per-cubic-second", "1000", "1000000.0"},
+        {"power", "megawatt", "kilogram-square-meter-per-cubic-second", "1000", "1000000000.0"},
+        {"power", "gigawatt", "kilogram-square-meter-per-cubic-second", "1000", "1e+12"},
+        {"power", "solar-luminosity", "kilogram-square-meter-per-cubic-second", "1000", "3.828e+29"},
+        {"pressure", "pascal", "kilogram-per-meter-square-second", "1000", "1000.0"},
+        {"pressure", "millimeter-of-mercury", "kilogram-per-meter-square-second", "1000", "13332.24"},
+        {"pressure", "hectopascal", "kilogram-per-meter-square-second", "1000", "100000.0"},
+        {"pressure", "millibar", "kilogram-per-meter-square-second", "1000", "100000.0"},
+        {"pressure", "kilopascal", "kilogram-per-meter-square-second", "1000", "1000000.0"},
+        {"pressure", "inch-hg", "kilogram-per-meter-square-second", "1000", "3386389.0"},
+        {"pressure", "pound-force-per-square-inch", "kilogram-meter-per-square-meter-square-second",
+         "1000", "6894757.0"},
+        {"pressure", "bar", "kilogram-per-meter-square-second", "1000", "100000000.0"},
+        {"pressure", "atmosphere", "kilogram-per-meter-square-second", "1000", "101325000.0"},
+        {"pressure", "megapascal", "kilogram-per-meter-square-second", "1000", "1000000000.0"},
+        {"resolution", "dot-per-inch", "pixel-per-meter", "1000", "39370.08"},
+        {"resolution", "pixel-per-inch", "pixel-per-meter", "1000", "39370.08"},
+        {"resolution", "dot-per-centimeter", "pixel-per-meter", "1000", "100000.0"},
+        {"resolution", "pixel-per-centimeter", "pixel-per-meter", "1000", "100000.0"},
+        {"speed", "kilometer-per-hour", "meter-per-second", "1000", "277.7778"},
+        {"speed", "mile-per-hour", "meter-per-second", "1000", "447.04"},
+        {"speed", "knot", "meter-per-second", "1000", "514.4444"},
+        {"speed", "meter-per-second", "meter-per-second", "1000", "1000.0"},
+        {"substance-amount", "mole", "item", "1000", "6.022141e+26"},
+        {"temperature", "fahrenheit", "kelvin", "1000", "810.9278"},
+        {"temperature", "kelvin", "kelvin", "1000", "1000.0"},
+        {"temperature", "celsius", "kelvin", "1000", "1273.15"},
+        {"typewidth", "em", "em", "1000", "1000.0"},
+        {"voltage", "volt", "kilogram-square-meter-per-cubic-second-ampere", "1000", "1000.0"},
+        {"volume", "cubic-centimeter", "cubic-meter", "1000", "0.001"},
+        {"volume", "milliliter", "cubic-meter", "1000", "0.001"},
+        {"volume", "teaspoon", "cubic-meter", "1000", "0.004928922"},
+        {"volume", "centiliter", "cubic-meter", "1000", "0.01"},
+        {"volume", "tablespoon", "cubic-meter", "1000", "0.01478676"},
+        {"volume", "cubic-inch", "cubic-meter", "1000", "0.01638706"},
+        {"volume", "fluid-ounce-imperial", "cubic-meter", "1000", "0.02841306"},
+        {"volume", "fluid-ounce", "cubic-meter", "1000", "0.02957353"},
+        {"volume", "deciliter", "cubic-meter", "1000", "0.1"},
+        {"volume", "cup", "cubic-meter", "1000", "0.2365882"},
+        {"volume", "cup-metric", "cubic-meter", "1000", "0.25"},
+        {"volume", "pint", "cubic-meter", "1000", "0.4731765"},
+        {"volume", "pint-metric", "cubic-meter", "1000", "0.5"},
+        {"volume", "quart", "cubic-meter", "1000", "0.9463529"},
+        {"volume", "liter", "cubic-meter", "1000", "1.0"},
+        {"volume", "gallon", "cubic-meter", "1000", "3.785412"},
+        {"volume", "gallon-imperial", "cubic-meter", "1000", "4.54609"},
+        {"volume", "cubic-foot", "cubic-meter", "1000", "28.31685"},
+        {"volume", "bushel", "cubic-meter", "1000", "35.23907"},
+        {"volume", "hectoliter", "cubic-meter", "1000", "100.0"},
+        {"volume", "barrel", "cubic-meter", "1000", "158.9873"},
+        {"volume", "cubic-yard", "cubic-meter", "1000", "764.5549"},
+        {"volume", "cubic-meter", "cubic-meter", "1000", "1000.0"},
+        {"volume", "megaliter", "cubic-meter", "1000", "1000000.0"},
+        {"volume", "acre-foot", "cubic-meter", "1000", "1233482.0"},
+        {"volume", "cubic-kilometer", "cubic-meter", "1000", "1e+12"},
+        {"volume", "cubic-mile", "cubic-meter", "1000", "4.168182e+12"},
+        {"year-duration", "month", "year", "1000", "83.33333"},
+        {"year-duration", "month-person", "year", "1000", "83.33333"},
+        {"year-duration", "year", "year", "1000", "1000.0"},
+        {"year-duration", "year-person", "year", "1000", "1000.0"},
+        {"year-duration", "decade", "year", "1000", "10000.0"},
+        {"year-duration", "century", "year", "1000", "100000.0"},
+    };
+
+    for (const auto &testCase : testCases) {
+        UErrorCode status = U_ZERO_ERROR;
+
+        MeasureUnit sourceUnit = MeasureUnit::forIdentifier(testCase.source, status);
+        MeasureUnit targetUnit = MeasureUnit::forIdentifier(testCase.target, status);
+
+        UnitConverter converter(sourceUnit, targetUnit, status);
+
+        number::impl::DecNum inputValue;
+        inputValue.setTo(testCase.inputValue, status);
+
+        number::impl::DecNum expectedValue;
+        expectedValue.setTo(testCase.expectedValue, status);
+
+        number::impl::DecNum actualConversionResult;
+        converter.convert(inputValue, actualConversionResult, status);
+
+        assertEqualsNear(testCase.category.data(), expectedValue, actualConversionResult, 0.01);
+    }
+}
+
+void UnitsTest::testCLDRUnitsTests2() {
+    struct {
+        const StringPiece category;
+        const StringPiece source;
+        const StringPiece target;
+        const StringPiece inputValue;
+        const StringPiece expectedValue;
+    } testCases[]{
+        {"area", "acre", "square-meter", "1000", "4046856.0"},
+    };
+
+    for (const auto &testCase : testCases) {
+        UErrorCode status = U_ZERO_ERROR;
+
+        MeasureUnit sourceUnit = MeasureUnit::forIdentifier(testCase.source, status);
+        MeasureUnit targetUnit = MeasureUnit::forIdentifier(testCase.target, status);
+
+        UnitConverter converter(sourceUnit, targetUnit, status);
+
+        number::impl::DecNum inputValue;
+        inputValue.setTo(testCase.inputValue, status);
+
+        number::impl::DecNum expectedValue;
+        expectedValue.setTo(testCase.expectedValue, status);
+
+        number::impl::DecNum actualConversionResult;
+        converter.convert(inputValue, actualConversionResult, status);
+
+        assertEqualsNear(testCase.category.data(), expectedValue, actualConversionResult, 0.01);
+    }
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */