unitsofmeasurement/uom-systems

Formatted UCUM unit cannot be parsed

stevenpaligo opened this issue · 3 comments

(I apologize in advance if this is supposed to be an Indriya issue instead. I'm not sure where there line is between that project and this one.)

It is possible to format a UCUM unit that cannot be parsed. See the following example. It formats the quantity as a string and then tries to parse it. The result is an exception:

IllegalArgumentException: one? not recognized (in 2.0 [one?]·rad/180.0 at index 5)

This is using systems-ucum version 1.0.

import javax.measure.Quantity;
import javax.measure.quantity.Angle;
import systems.uom.ucum.UCUM;
import tech.units.indriya.format.SimpleQuantityFormat;
import tech.units.indriya.quantity.Quantities;

public class Example {

  public static void main(String[] args) {

    Quantity<Angle> originalQty = Quantities.getQuantity(2.0, UCUM.DEGREE);
    String originalQtyString = SimpleQuantityFormat.getInstance().format(originalQty);
    Quantity<Angle> parsedQty = Quantities.getQuantity(originalQtyString).asType(Angle.class);

  }
}
keilw commented

No it seems OK here, because UCUM has its own UnitFormat implementation. Did you try the 2.0-SNAPSHOT to reproduce it there as well?

I just tried it in 2.0-SNAPSHOT and it throws a similar exception:

IllegalArgumentException: one*3.141592653589793238462643383279503·rad/180

keilw commented

Hi, please have a look at UCUMFormatDemo. It shows, how to format and parse UCUM units. The SimpleQuantityFormat or SimpleUnitFormat both are not optimized for the UCUM system, which is why they won't work with most UCUM units.
The use of a matching UCUMFormat (both CI or CS work, Print is not meant to parse, so it's format only) combined in a NumberDelimiterQuantityFormat works for your example. The extra cast to ComparableQuantity is only to demonstrate, they are equivalent, equals() won't work because the number type may change, e.g. it is optimized here to only take an integer number, so Quantity.equals() would not work. If you don't need that comparison, you can use the earlier approach with asType(). Please feel free to add a documentation task (in https://github.com/unitsofmeasurement/uom-guide) because this is another area which can use a bit of explanation, but it works, you just have to use the correct formatters for the UCUM units.