javaunits-of-measurement

US/Imperial units with Java's Units of Measurement API


I'm only seeing metric units in the Indriya 2.0.4 reference implementation of the Java Units of Measurement standard. Surely other people have wanted to work with feet, inches, and miles, but I can't find anything about that. Can anyone tell me what I'm missing here?

I can do Quantity<Mass> weight = Quantities.getQuantity(1, Units.KILOGRAM);, so where is Quantity<Mass> weight = Quantities.getQuantity(1, Units.POUND);?


Solution

  • For measurements which are wider than just SI units, you can use some of the other APIs in the Units of Measurement project (which includes the indriya API).

    Specifically, the CLDR and USCustomary classes may be of interest. However, I have not had success combining units from different classes, e.g. for conversions (see the commented-out code below).

    Some examples:

    import javax.measure.Quantity;
    import javax.measure.quantity.Length;
    import javax.measure.quantity.Mass;
    
    import systems.uom.unicode.CLDR;
    import systems.uom.common.USCustomary;
    
    import tec.units.ri.quantity.Quantities;
    import tec.units.ri.unit.Units;
    
    ...
    
    Quantity<Mass> weight1 = Quantities.getQuantity(1, Units.KILOGRAM);
    Quantity<Mass> weight2 = Quantities.getQuantity(1, USCustomary.POUND);
            
    // javax.measure.IncommensurableException: kg is not compatible with lb
    //Double d2 = Units.KILOGRAM.getConverterTo(CLDR.POUND).convert(1);
    
    Quantity<Mass> weight3 = Quantities.getQuantity(123.45, CLDR.GRAM);
    Quantity<Mass> weight4 = Quantities.getQuantity(123.45, CLDR.OUNCE);
    Quantity<Mass> weight5 = Quantities.getQuantity(123.45, CLDR.OUNCE_TROY);
            
    Double ounces = CLDR.GRAM.getConverterTo(CLDR.OUNCE)
            .convert(weight3.getValue()).doubleValue();
    System.out.println(weight3.getValue() + " grams = " + ounces + " ounces");
            
    Quantity<Length> dist1 = Quantities.getQuantity(123.45, CLDR.KILOMETER);
    Double miles = CLDR.KILOMETER.getConverterTo(CLDR.MILE)
            .convert(dist1.getValue()).doubleValue();
    System.out.println(dist1.getValue() + " kilometers = " + miles + " miles");
    

    The outputs from the above examples are:

    123.45 grams = 4.354570602675702 ounces
    123.45 kilometers = 76.70827368169888 miles
    

    My POM dependencies for this are:

    <dependencies>
        <dependency>
            <groupId>javax.measure</groupId>
            <artifactId>unit-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>tec.units</groupId>
            <artifactId>unit-ri</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>systems.uom</groupId>
            <artifactId>systems-unicode</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>systems.uom</groupId>
            <artifactId>systems-common</artifactId>
            <version>2.0.2</version>
        </dependency>
        <dependency>
            <groupId>systems.uom</groupId>
            <artifactId>systems-quantity</artifactId>
            <version>2.0.2</version>
        </dependency>
    </dependencies>