Java units of measurement libraries other than JSR-275 and Units of Measure API

1k views Asked by At

Are there any Java libraries dealing with units of measurement except for JSR 275 (rejected and abandoned) and Units of Measure API (which doesn't seem to have any production-quality implementations)?

3

There are 3 answers

0
John On

I have written a units library that does not use static typesetting (as in many practical applications I encountered this would have been more cumbersome that I would like such a library to be). It is designed to handle string based units as well as sharper defined units. Some of the supported features include:

  • conversions of values, e.g.:

    Units.convert(3, "m", "mm");
    Units.convert(3, SiBaseUnit.METER, "mm");
    

    would both return 3000.

  • simplification of string based units, e.g.:

    Units.simplify("kg^3 m^4 s^-6 A^-1");
    

    would return "J^2 T".

  • finding the names of a unit in a specific context, e.g.:

    Units.inContext("lx s", UnitContextMatch.COMPATIBLE, PhysicsContext.PHOTOMETRY)
    

    would return a navigable set containing ("luminous exposure").

  • supports SI units, binary units, imperial units, US customary units, atomic units, planck units and many more. The user can also easily define own units.

  • fully supports arbitrary logarithmic units, e.g.

    LevelUnit.BEL.inReferenceTo(1, Unit.of("mV")); // automatically determines ref type -> root power
    LevelUnit.BEL.inReferenceTo(1, Unit.of("W"), LevelUnitReferenceType.POWER); // specify type explicitly
    Unit.of("ln(re 1 nA)") == LevelUnit.NEPER.inReferenceTo(1, Unit.of("nA")); // true
    
  • supports SI prefixes, binary prefixes and allows the user to easily implement own prefixes

  • Can handle unknown units if not relevant, e.g.:

    Units.convert(3, "m^2 this_is_not_a_unit", "mm^2 this_is_not_a_unit");
    

    would return 3e6, as the unknown unit this_is_not_a_unit is the same on both sides of the conversion.

  • for performance critical parts of the code one can obtain the conversion factor (if the conversion is purely multiplicative), e.g.:

    Units.factor("kg", "t");
    

    will return 1e-3.

  • Allows to check for equivalence, e.g.

    Units.equivalent(1, "s", "min");
    

    will return false, as 1min is not the same as 1s. On the other hand, checking for convertibility

    Units.convertible("s", "min");
    

    will return true.

  • tightly integrated in the coordinates library (as of Java 16 this library still requires preview-features, but as of Java 17 it will production ready)

The constants are implemented via a Constant interface that supports e.g.:

  • definition of own constants, e.g.

    // (3 ± 0.2) mole
    Constant.of(3, 0.2, "mole");
    
  • chaining commands, e.g.

    // constant with the distance travelled by light in vacuum in (2 ± 0) seconds as value
    PhysicsConstant.SPEED_OF_LIGHT_IN_VACUUM.mul(2, 0, SiBaseUnit.SECOND);
    
    // constant of the elementary charge per (electron) mass
    PhysicsConstant.ELEMENTARY_CHARGE.div(PhysicsConstant.ELECTRON_MASS);
    
    Constant c = Constant.of(3, 0.2, "mole");
    PhysicsConstant.SHIELDING_DIFFERENCE_OF_T_AND_P_IN_HT.mul(c);
    
  • (simple) uncertainty propagation

  • the Constant interface provides default implementations for the Texable interface from the jatex module, such that a constant can easily return proper LaTeX code.

  • properly documented implementations for most of the physics constants as defined by NIST, as well as some mathematical constants.

1
blah On
1
Piotr_J. On

I have created an opensource Unitility 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}

Maybe this will be helpful if you are looking for something simple. It supports a selection of most typical physical quantities and its units for SI and IMPERIAL units. If you need any specific unit or quantity to be added - just let me know.

Edit: 2024.01.16