Reputation: 27886
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);
?
Upvotes: 1
Views: 3001
Reputation: 21
I have created an opensource Unitility library for working with physical quantities and units of measurements including easy conversion between them. Example of usage:
// Creating temperature instance of specified units
Temperature temperature = Temperature.ofCelsius(20.5); // {20.50 °C}
// Getting converted value for calculations
double valueInCelsius = temperature.getInCelsius(); // 20.50 °C
double valueInFahrenheits = temperature.getInFahrenheits(); // 68.90 °F
// Checking property current unit, value, and value in base unit
TemperatureUnits unit = temperature.getUnit(); // CELSIUS
TemperatureUnits baseUnit = unit.getBaseUnit(); // KELVIN
// Changing property unit and converting back to base unit
Temperature tempInFahrenheits = temperature.toUnit(TemperatureUnits.FAHRENHEIT);
Temperature tempInKelvins = temperature.toBaseUnit();
Additionally, logical and basic math operations are supported within quantities of the same type:
// Logic operation example:
Temperature smallerTemp = Temperature.ofCelsius(-20.0);
Temperature greaterTemp = Temperature.ofCelsius(0.0);
smallerTemp.isLowerThan(greaterTemp);
greaterTemp.isGreaterThan(smallerTemp);
// Math operation example:
Temperature sourceTemperature = Temperature.ofCelsius(20);
Temperature temperatureToAdd = Temperature.ofKelvins(293.15);
Temperature actualTemperature = sourceTemperature.add(temperatureToAdd); // {40°C}
It includes variety of SI and imperial units, but it is designed in a way, that while working with PhysicalQuantity you dont have to care about it. You can define any quantity with SI or Imperial unit, but internally it is converted to the base unit. When you want to extract value in a specific unit, you simply chose correct method representing your desired unit SI or Imperial for a given quantity type. Library has modules for SpringBoot and Quarkus support and module for Jakarta Validators, what may be useful in web applications, for an example:
@GetMapping("/dry-air")
DryAirResponse getDryAir(@RequestParam @PhysicalRange(min = "-150oC", max = "100F") Temperature temperature);
If you need any specific set of units to be added for your engineering field, just let me know!
Upvotes: 1
Reputation: 21902
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>
Upvotes: 5