001/* 002 * Units of Measurement Implementation for Java SE 003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, 008 * are permitted provided that the following conditions are met: 009 * 010 * 1. Redistributions of source code must retain the above copyright notice, 011 * this list of conditions and the following disclaimer. 012 * 013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions 014 * and the following disclaimer in the documentation and/or other materials provided with the distribution. 015 * 016 * 3. Neither the name of JSR-363 nor the names of its contributors may be used to endorse or promote products 017 * derived from this software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package tec.uom.se.unit; 031 032import static tec.uom.se.AbstractUnit.ONE; 033import tec.uom.lib.common.function.Nameable; 034import tec.uom.se.AbstractSystemOfUnits; 035import tec.uom.se.AbstractUnit; 036import tec.uom.se.function.AddConverter; 037import tec.uom.se.function.PiMultiplierConverter; 038import tec.uom.se.function.RationalConverter; 039import tec.uom.se.quantity.QuantityDimension; 040 041import javax.measure.Quantity; 042import javax.measure.Unit; 043import javax.measure.quantity.Acceleration; 044import javax.measure.quantity.AmountOfSubstance; 045import javax.measure.quantity.Angle; 046import javax.measure.quantity.Area; 047import javax.measure.quantity.CatalyticActivity; 048import javax.measure.quantity.Dimensionless; 049import javax.measure.quantity.ElectricCapacitance; 050import javax.measure.quantity.ElectricCharge; 051import javax.measure.quantity.ElectricConductance; 052import javax.measure.quantity.ElectricCurrent; 053import javax.measure.quantity.ElectricInductance; 054import javax.measure.quantity.ElectricPotential; 055import javax.measure.quantity.ElectricResistance; 056import javax.measure.quantity.Energy; 057import javax.measure.quantity.Force; 058import javax.measure.quantity.Frequency; 059import javax.measure.quantity.Illuminance; 060import javax.measure.quantity.Length; 061import javax.measure.quantity.LuminousFlux; 062import javax.measure.quantity.LuminousIntensity; 063import javax.measure.quantity.MagneticFlux; 064import javax.measure.quantity.MagneticFluxDensity; 065import javax.measure.quantity.Mass; 066import javax.measure.quantity.Power; 067import javax.measure.quantity.Pressure; 068import javax.measure.quantity.RadiationDoseAbsorbed; 069import javax.measure.quantity.RadiationDoseEffective; 070import javax.measure.quantity.Radioactivity; 071import javax.measure.quantity.SolidAngle; 072import javax.measure.quantity.Speed; 073import javax.measure.quantity.Temperature; 074import javax.measure.quantity.Time; 075import javax.measure.quantity.Volume; 076import javax.measure.spi.SystemOfUnits; 077 078/** 079 * <p> 080 * This class defines commonly used units. 081 * 082 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 083 * @version 1.0.4, June 6, 2017 084 * @since 1.0 085 */ 086public class Units extends AbstractSystemOfUnits implements Nameable { 087 088 protected Units() { 089 } 090 091 private static final Units INSTANCE = new Units(); 092 093 public String getName() { 094 return Units.class.getSimpleName(); 095 } 096 097 // ////////////// 098 // BASE UNITS // 099 // ////////////// 100 101 /** 102 * The SI base unit for electric current quantities (standard name <code>A</code>). The Ampere is that constant current which, if maintained in two 103 * straight parallel conductors of infinite length, of negligible circular cross-section, and placed 1 meter apart in vacuum, would produce between 104 * these conductors a force equal to 2 * 10-7 newton per meter of length. It is named after the French physicist Andre Ampere (1775-1836). 105 * 106 * @implNote SI Base Unit 107 */ 108 public static final Unit<ElectricCurrent> AMPERE = addUnit(new BaseUnit<ElectricCurrent>("A", QuantityDimension.ELECTRIC_CURRENT), 109 ElectricCurrent.class); 110 111 /** 112 * The SI base unit for luminous intensity quantities (standard name <code>cd</code>). The candela is the luminous intensity, in a given direction, 113 * of a source that emits monochromatic radiation of frequency 540 * 1012 hertz and that has a radiant intensity in that direction of 1/683 watt per 114 * steradian 115 * 116 * @see <a href="http://en.wikipedia.org/wiki/Candela"> Wikipedia: Candela</a> 117 * 118 * @implNote SI Base Unit 119 */ 120 public static final Unit<LuminousIntensity> CANDELA = addUnit(new BaseUnit<LuminousIntensity>("cd", QuantityDimension.LUMINOUS_INTENSITY), 121 LuminousIntensity.class); 122 123 /** 124 * The SI base unit for thermodynamic temperature quantities (standard name <code>K</code>). The kelvin is the 1/273.16th of the thermodynamic 125 * temperature of the triple point of water. It is named after the Scottish mathematician and physicist William Thomson 1st Lord Kelvin (1824-1907) 126 * 127 * @implNote SI Base Unit 128 */ 129 public static final Unit<Temperature> KELVIN = addUnit(new BaseUnit<Temperature>("K", QuantityDimension.TEMPERATURE), Temperature.class); 130 131 /** 132 * The SI base unit for mass quantities (standard name <code>kg</code>). It is the only SI unit with a prefix as part of its name and symbol. The 133 * kilogram is equal to the mass of an international prototype in the form of a platinum-iridium cylinder kept at Sevres in France. 134 * 135 * @see #GRAM 136 * 137 * @implNote SI Base Unit 138 */ 139 public static final Unit<Mass> KILOGRAM = addUnit(new BaseUnit<Mass>("kg", QuantityDimension.MASS), Mass.class); 140 141 /** 142 * The SI base unit for length quantities (standard name <code>m</code>). One metre was redefined in 1983 as the distance traveled by light in a 143 * vacuum in 1/299,792,458 of a second. 144 * 145 * @implNote SI Base Unit 146 */ 147 public static final Unit<Length> METRE = addUnit(new BaseUnit<>("m", QuantityDimension.LENGTH), Length.class); 148 149 /** 150 * The SI base unit for amount of substance quantities (standard name <code>mol</code>). The mole is the amount of substance of a system which 151 * contains as many elementary entities as there are atoms in 0.012 kilogram of carbon 12. 152 * 153 * @implNote SI Base Unit 154 */ 155 public static final Unit<AmountOfSubstance> MOLE = addUnit(new BaseUnit<>("mol", QuantityDimension.AMOUNT_OF_SUBSTANCE), AmountOfSubstance.class); 156 157 /** 158 * The SI base unit for duration quantities (standard name <code>s</code>). It is defined as the duration of 9,192,631,770 cycles of radiation 159 * corresponding to the transition between two hyperfine levels of the ground state of cesium (1967 Standard). 160 * 161 * @implNote SI Base Unit 162 */ 163 public static final Unit<Time> SECOND = addUnit(new BaseUnit<>("s", QuantityDimension.TIME), Time.class); 164 165 // ////////////////////////////// 166 // SI DERIVED ALTERNATE UNITS // 167 // ////////////////////////////// 168 169 /** 170 * The SI derived unit for mass quantities (standard name <code>g</code>). The base unit for mass quantity is {@link #KILOGRAM}. 171 */ 172 public static final Unit<Mass> GRAM = addUnit(KILOGRAM.divide(1000)); 173 // = new TransformedUnit(KILOGRAM, MetricPrefix.KILO.getConverter()); 174 175 /** 176 * The SI unit for plane angle quantities (standard name <code>rad</code>). One radian is the angle between two radii of a circle such that the 177 * length of the arc between them is equal to the radius. 178 */ 179 public static final Unit<Angle> RADIAN = addUnit(new AlternateUnit<>(ONE, "rad"), Angle.class); 180 181 /** 182 * The SI unit for solid angle quantities (standard name <code>sr</code>). One steradian is the solid angle subtended at the center of a sphere by 183 * an area on the surface of the sphere that is equal to the radius squared. The total solid angle of a sphere is 4*Pi steradians. 184 */ 185 public static final Unit<SolidAngle> STERADIAN = addUnit(new AlternateUnit<SolidAngle>(ONE, "sr"), SolidAngle.class); 186 187 /** 188 * The SI unit for frequency (standard name <code>Hz</code>). A unit of frequency equal to one cycle per second. After Heinrich Rudolf Hertz 189 * (1857-1894), German physicist who was the first to produce radio waves artificially. 190 */ 191 public static final Unit<Frequency> HERTZ = addUnit(new AlternateUnit<Frequency>(ONE.divide(SECOND), "Hz"), Frequency.class); 192 193 /** 194 * The SI unit for force (standard name <code>N</code>). One newton is the force required to give a mass of 1 kilogram an Force of 1 metre per 195 * second per second. It is named after the English mathematician and physicist Sir Isaac Newton (1642-1727). 196 */ 197 public static final Unit<Force> NEWTON = addUnit(new AlternateUnit<Force>(METRE.multiply(KILOGRAM).divide(SECOND.pow(2)), "N"), Force.class); 198 199 /** 200 * The SI unit for pressure, stress (standard name <code>Pa</code>). One pascal is equal to one newton per square meter. It is named after the 201 * French philosopher and mathematician Blaise Pascal (1623-1662). 202 */ 203 @SuppressWarnings({ "unchecked", "rawtypes" }) 204 public static final Unit<Pressure> PASCAL = addUnit(new AlternateUnit(NEWTON.divide(METRE.pow(2)), "Pa"), Pressure.class); 205 206 /** 207 * The SI unit for energy, work, quantity of heat (<code>J</code>). One joule is the amount of work done when an applied force of 1 newton moves 208 * through a distance of 1 metre in the direction of the force. It is named after the English physicist James Prescott Joule (1818-1889). 209 */ 210 public static final Unit<Energy> JOULE = addUnit(new AlternateUnit<Energy>(NEWTON.multiply(METRE), "J"), Energy.class); 211 212 /** 213 * The SI unit for power, radiant, flux (standard name <code>W</code>). One watt is equal to one joule per second. It is named after the British 214 * scientist James Watt (1736-1819). 215 */ 216 public static final AlternateUnit<Power> WATT = addUnit(new AlternateUnit<Power>(JOULE.divide(SECOND), "W"), Power.class); 217 218 /** 219 * The SI unit for electric charge, quantity of electricity (standard name <code>C</code>). One Coulomb is equal to the quantity of charge 220 * transferred in one second by a steady current of one ampere. It is named after the French physicist Charles Augustin de Coulomb (1736-1806). 221 */ 222 public static final Unit<ElectricCharge> COULOMB = addUnit(new AlternateUnit<ElectricCharge>(SECOND.multiply(AMPERE), "C"), ElectricCharge.class); 223 224 /** 225 * The SI unit for electric potential difference, electromotive force (standard name <code>V</code>). One Volt is equal to the difference of 226 * electric potential between two points on a conducting wire carrying a constant current of one ampere when the power dissipated between the points 227 * is one watt. It is named after the Italian physicist Count Alessandro Volta (1745-1827). 228 */ 229 public static final Unit<ElectricPotential> VOLT = addUnit(new AlternateUnit<ElectricPotential>(WATT.divide(AMPERE), "V"), ElectricPotential.class); 230 231 /** 232 * The SI unit for capacitance (standard name <code>F</code>). One Farad is equal to the capacitance of a capacitor having an equal and opposite 233 * charge of 1 coulomb on each plate and a potential difference of 1 volt between the plates. It is named after the British physicist and chemist 234 * Michael Faraday (1791-1867). 235 */ 236 public static final Unit<ElectricCapacitance> FARAD = addUnit(new AlternateUnit<ElectricCapacitance>(COULOMB.divide(VOLT), "F"), 237 ElectricCapacitance.class); 238 239 /** 240 * The SI unit for electric resistance (standard name <code>Ohm</code>). One Ohm is equal to the resistance of a conductor in which a current of one 241 * ampere is produced by a potential of one volt across its terminals. It is named after the German physicist Georg Simon Ohm (1789-1854). 242 */ 243 public static final Unit<ElectricResistance> OHM = addUnit(new AlternateUnit<ElectricResistance>(VOLT.divide(AMPERE), "Ω"), 244 ElectricResistance.class); 245 246 /** 247 * The SI unit for electric conductance (standard name <code>S</code>). One Siemens is equal to one ampere per volt. It is named after the German 248 * engineer Ernst Werner von Siemens (1816-1892). 249 */ 250 public static final Unit<ElectricConductance> SIEMENS = addUnit(new AlternateUnit<ElectricConductance>(AMPERE.divide(VOLT), "S"), 251 ElectricConductance.class); 252 253 /** 254 * The SI unit for magnetic flux (standard name <code>Wb</code>). One Weber is equal to the magnetic flux that in linking a circuit of one turn 255 * produces in it an electromotive force of one volt as it is uniformly reduced to zero within one second. It is named after the German physicist 256 * Wilhelm Eduard Weber (1804-1891). 257 */ 258 public static final Unit<MagneticFlux> WEBER = addUnit(new AlternateUnit<MagneticFlux>(VOLT.multiply(SECOND), "Wb"), MagneticFlux.class); 259 260 /** 261 * The alternate unit for magnetic flux density (standard name <code>T</code>). One Tesla is equal equal to one weber per square metre. It is named 262 * after the Serbian-born American electrical engineer and physicist Nikola Tesla (1856-1943). 263 */ 264 public static final Unit<MagneticFluxDensity> TESLA = addUnit(new AlternateUnit<MagneticFluxDensity>(WEBER.divide(METRE.pow(2)), "T"), 265 MagneticFluxDensity.class); 266 267 /** 268 * The alternate unit for inductance (standard name <code>H</code>). One Henry is equal to the inductance for which an induced electromotive force 269 * of one volt is produced when the current is varied at the rate of one ampere per second. It is named after the American physicist Joseph Henry 270 * (1791-1878). 271 */ 272 public static final Unit<ElectricInductance> HENRY = addUnit(new AlternateUnit<ElectricInductance>(WEBER.divide(AMPERE), "H"), 273 ElectricInductance.class); 274 275 /** 276 * The SI unit for Celsius temperature (standard name <code>Cel</code>). This is a unit of temperature such as the freezing point of water (at one 277 * atmosphere of pressure) is 0 Cel, while the boiling point is 100 Cel. 278 */ 279 @SuppressWarnings({ "rawtypes", "unchecked" }) 280 public static final Unit<Temperature> CELSIUS = addUnit(new TransformedUnit(KELVIN, new AddConverter(273.15))); 281 // Not mapping to Temperature since temperature is mapped to Kelvin. 282 283 /** 284 * The SI unit for luminous flux (standard name <code>lm</code>). One Lumen is equal to the amount of light given out through a solid angle by a 285 * source of one candela intensity radiating equally in all directions. 286 */ 287 public static final Unit<LuminousFlux> LUMEN = addUnit(new AlternateUnit<LuminousFlux>(CANDELA.multiply(STERADIAN), "lm"), LuminousFlux.class); 288 289 /** 290 * The SI unit for illuminance (standard name <code>lx</code>). One Lux is equal to one lumen per square metre. 291 */ 292 public static final Unit<Illuminance> LUX = addUnit(new AlternateUnit<Illuminance>(LUMEN.divide(METRE.pow(2)), "lx"), Illuminance.class); 293 294 /** 295 * The SI unit for activity of a radionuclide (standard name <code>Bq</code> ). One becquerel is the radiation caused by one disintegration per 296 * second. It is named after the French physicist, Antoine-Henri Becquerel (1852-1908). 297 */ 298 public static final Unit<Radioactivity> BECQUEREL = addUnit(new AlternateUnit<Radioactivity>(ONE.divide(SECOND), "Bq"), Radioactivity.class); 299 300 /** 301 * The SI unit for absorbed dose, specific energy (imparted), kerma (standard name <code>Gy</code>). One gray is equal to the dose of one joule of 302 * energy absorbed per one kilogram of matter. It is named after the British physician L. H. Gray (1905-1965). 303 */ 304 public static final Unit<RadiationDoseAbsorbed> GRAY = addUnit(new AlternateUnit<RadiationDoseAbsorbed>(JOULE.divide(KILOGRAM), "Gy"), 305 RadiationDoseAbsorbed.class); 306 307 /** 308 * The SI unit for dose equivalent (standard name <code>Sv</code>). One Sievert is equal is equal to the actual dose, in grays, multiplied by a 309 * "quality factor" which is larger for more dangerous forms of radiation. It is named after the Swedish physicist Rolf Sievert (1898-1966). 310 */ 311 public static final Unit<RadiationDoseEffective> SIEVERT = addUnit(new AlternateUnit<RadiationDoseEffective>(JOULE.divide(KILOGRAM), "Sv"), 312 RadiationDoseEffective.class); 313 314 /** 315 * The SI unit for catalytic activity (standard name <code>kat</code>). 316 */ 317 public static final Unit<CatalyticActivity> KATAL = addUnit(new AlternateUnit<CatalyticActivity>(MOLE.divide(SECOND), "kat"), 318 CatalyticActivity.class); 319 320 // //////////////////////////// 321 // SI DERIVED PRODUCT UNITS // 322 // //////////////////////////// 323 324 /** 325 * The SI unit for velocity quantities (standard name <code>m/s</code>). 326 */ 327 public static final Unit<Speed> METRE_PER_SECOND = addUnit(new ProductUnit<>(METRE.divide(SECOND)), Speed.class); 328 329 /** 330 * The SI unit for acceleration quantities (standard name <code>m/s2</code> ). 331 */ 332 public static final Unit<Acceleration> METRE_PER_SQUARE_SECOND = addUnit(new ProductUnit<>(METRE_PER_SECOND.divide(SECOND)), Acceleration.class); 333 334 /** 335 * The SI unit for area quantities (standard name <code>m2</code>). 336 */ 337 public static final Unit<Area> SQUARE_METRE = addUnit(new ProductUnit<>(METRE.multiply(METRE)), Area.class); 338 339 /** 340 * The SI unit for volume quantities (standard name <code>m3</code>). 341 */ 342 public static final Unit<Volume> CUBIC_METRE = addUnit(new ProductUnit<Volume>(SQUARE_METRE.multiply(METRE)), Volume.class); 343 344 /** 345 * A unit of velocity expressing the number of international {@link #KILOMETRE kilometres} per {@link #HOUR hour} (abbreviation <code>km/h</code>). 346 */ 347 public static final Unit<Speed> KILOMETRE_PER_HOUR = addUnit(METRE_PER_SECOND.multiply(0.277778d)).asType(Speed.class); 348 349 // /////////////////////////////////////////////////////////////// 350 // Common Units outside the SI that are accepted for use with the SI. // 351 // /////////////////////////////////////////////////////////////// 352 353 /** 354 * A dimensionless unit accepted for use with SI units (standard name <code>%</code>). 355 */ 356 public static final Unit<Dimensionless> PERCENT = addUnit(new TransformedUnit<>(ONE, new RationalConverter(1, 100))); 357 358 // //////// 359 // Time // 360 // //////// 361 /** 362 * A time unit accepted for use with SI units (standard name <code>min</code>). 363 */ 364 public static final Unit<Time> MINUTE = addUnit(new TransformedUnit<>("min", SECOND, SECOND, new RationalConverter(60, 1))); 365 366 /** 367 * A time unit accepted for use with SI units (standard name <code>h</code> ). 368 */ 369 public static final Unit<Time> HOUR = addUnit(new TransformedUnit<>("h", SECOND, SECOND, new RationalConverter(60 * 60, 1))); 370 371 /** 372 * A time unit accepted for use with SI units (standard name <code>d</code> ). 373 */ 374 public static final Unit<Time> DAY = addUnit(new TransformedUnit<>("d", SECOND, SECOND, new RationalConverter(24 * 60 * 60, 1))); 375 376 /** 377 * A unit of duration equal to 7 {@link #DAY} (standard name <code>week</code>). 378 */ 379 public static final Unit<Time> WEEK = addUnit(DAY.multiply(7)); 380 381 /** 382 * A time unit accepted for use with SI units (standard name <code>y</code> ). 383 */ 384 public static final Unit<Time> YEAR = addUnit(Units.DAY.multiply(365.2525)); 385 386 /** 387 * An angle unit accepted for use with SI units (standard name <code>deg</code>). 388 * 389 * @deprecated Use from NonSI 390 */ 391 public static final Unit<Angle> DEGREE_ANGLE = addUnit(new TransformedUnit<>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter( 392 1, 180)))); 393 394 /** 395 * An angle unit accepted for use with SI units (standard name <code>'</code>). 396 * 397 * @deprecated Use from SI 398 */ 399 public static final Unit<Angle> MINUTE_ANGLE = addUnit(new TransformedUnit<>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter( 400 1, 180 * 60)))); 401 402 /** 403 * An angle unit accepted for use with SI units (standard name <code>''</code>). 404 * 405 * @deprecated Use from SI 406 */ 407 public static final Unit<Angle> SECOND_ANGLE = addUnit(new TransformedUnit<>(RADIAN, new PiMultiplierConverter().concatenate(new RationalConverter( 408 1, 180 * 60 * 60)))); 409 410 /** 411 * A volume unit accepted for use with SI units (standard name <code>l</code>). 412 * 413 * @see <a href="https://en.wikipedia.org/wiki/Litre"> Wikipedia: Litre</a> 414 */ 415 public static final Unit<Volume> LITRE = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, new TransformedUnit<Volume>(CUBIC_METRE, 416 new RationalConverter(1, 1000)), "Litre", "l"); 417 418 /** 419 * Returns the unique instance of this class. 420 * 421 * @return the Units instance. 422 */ 423 public static SystemOfUnits getInstance() { 424 return INSTANCE; 425 } 426 427 static { 428 // have to add AbstractUnit.ONE as Dimensionless, too 429 addUnit(AbstractUnit.ONE); 430 INSTANCE.quantityToUnit.put(Dimensionless.class, AbstractUnit.ONE); 431 } 432 433 /** 434 * Adds a new unit not mapped to any specified quantity type. 435 * 436 * @param unit 437 * the unit being added. 438 * @return <code>unit</code>. 439 */ 440 private static <U extends Unit<?>> U addUnit(U unit) { 441 INSTANCE.units.add(unit); 442 return unit; 443 } 444 445 /** 446 * Adds a new unit and maps it to the specified quantity type. 447 * 448 * @param unit 449 * the unit being added. 450 * @param type 451 * the quantity type. 452 * @return <code>unit</code>. 453 */ 454 private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) { 455 INSTANCE.units.add(unit); 456 INSTANCE.quantityToUnit.put(type, unit); 457 return unit; 458 } 459}