diff --git a/src/main/java/org/icatproject/utils/IcatUnits.java b/src/main/java/org/icatproject/utils/IcatUnits.java
new file mode 100644
index 0000000..285cc0b
--- /dev/null
+++ b/src/main/java/org/icatproject/utils/IcatUnits.java
@@ -0,0 +1,77 @@
+package org.icatproject.utils;
+
+import javax.measure.IncommensurableException;
+import javax.measure.UnconvertibleException;
+import javax.measure.Unit;
+import javax.measure.UnitConverter;
+import javax.measure.format.MeasurementParseException;
+
+import tech.units.indriya.format.SimpleUnitFormat;
+
+/**
+ * Utility to perform conversions to SI (System) units.
+ */
+public class IcatUnits {
+
+ /**
+ * Holds the SI units and value for a quantity. If the units provided at construction could not be parsed, then these will be null.
+ */
+ public class SystemValue {
+ public String units = null;
+ public Double value = null;
+
+ /**
+ * Converts value units into an SI quantity.
+ *
+ * @param value Quantity in (potentially) non-SI units.
+ * @param units Units of the provided value.
+ */
+ public SystemValue(Double value, String units) {
+ try {
+ Unit> unit = unitFormat.parse(units);
+ Unit> systemUnit = unit.getSystemUnit();
+ this.units = systemUnit.getName();
+ if (value == null) {
+ return;
+ }
+ UnitConverter converter = unit.getConverterToAny(systemUnit);
+ this.value = converter.convert(value.doubleValue());
+ } catch (MeasurementParseException | UnconvertibleException | IncommensurableException e) {
+ // If the units can't be parsed, or the value converted, then just return
+ return;
+ }
+ }
+ }
+
+ private static final SimpleUnitFormat unitFormat = SimpleUnitFormat.getInstance();
+
+ /**
+ * Creates instance with any aliasing.
+ */
+ public IcatUnits() {
+ }
+
+ /**
+ * In addition to the standard names and prefixes, allows aliasing other terms
+ * for a unit. Note that Unit should be refered to by the symbol specified in
+ * the
+ * Indriya
+ * documentation, but the aliases can be any string. However, OoM prefixes
+ * will not be applied to aliases. For example, "mK" would be understood as
+ * 0.001K, but if "Kelvin" is aliased than "mKelvin" will not be understood.
+ *
+ * @param aliasOptions String with the format ": ,
+ * : ..."
+ */
+ public IcatUnits(String aliasOptions) {
+ for (String unitAliases : aliasOptions.split(",")) {
+ String[] splitUnitAliases = unitAliases.split(":");
+ Unit> unit = unitFormat.parse(splitUnitAliases[0].trim());
+ for (String alias : splitUnitAliases[1].trim().split("\\s+")) {
+ unitFormat.alias(unit, alias);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/icatproject/utils/TestIcatUnits.java b/src/test/java/org/icatproject/utils/TestIcatUnits.java
new file mode 100644
index 0000000..fa2705e
--- /dev/null
+++ b/src/test/java/org/icatproject/utils/TestIcatUnits.java
@@ -0,0 +1,45 @@
+package org.icatproject.utils;
+
+import static org.junit.Assert.assertEquals;
+import org.icatproject.utils.IcatUnits.SystemValue;
+import org.junit.Test;
+
+public class TestIcatUnits {
+ @Test
+ public void testArguments() {
+ // Both null
+ IcatUnits icatUnits = new IcatUnits();
+ SystemValue systemValue = icatUnits.new SystemValue(null, "impossible to parse");
+ assertEquals(null, systemValue.units);
+ assertEquals(null, systemValue.value);
+
+ // Unit parsed, value null
+ systemValue = icatUnits.new SystemValue(null, "K");
+ assertEquals("Kelvin", systemValue.units);
+ assertEquals(null, systemValue.value);
+
+ // Unit parsed, value converted
+ systemValue = icatUnits.new SystemValue(1., "GK");
+ assertEquals("Kelvin", systemValue.units);
+ assertEquals(new Double(1e9), systemValue.value);
+ }
+
+ @Test
+ public void testAliasing() {
+ IcatUnits icatUnits = new IcatUnits();
+ SystemValue systemValue = icatUnits.new SystemValue(null, "celsius");
+ assertEquals(null, systemValue.units);
+ systemValue = icatUnits.new SystemValue(null, "degC");
+ assertEquals(null, systemValue.units);
+ systemValue = icatUnits.new SystemValue(null, "kelvin");
+ assertEquals(null, systemValue.units);
+
+ icatUnits = new IcatUnits("\u2103: celsius degC, K: kelvin");
+ systemValue = icatUnits.new SystemValue(null, "celsius");
+ assertEquals("Kelvin", systemValue.units);
+ systemValue = icatUnits.new SystemValue(null, "degC");
+ assertEquals("Kelvin", systemValue.units);
+ systemValue = icatUnits.new SystemValue(null, "kelvin");
+ assertEquals("Kelvin", systemValue.units);
+ }
+}
\ No newline at end of file