001/* 002 * Units of Measurement Systems 003 * Copyright (c) 2005-2021, Jean-Marie Dautelle, Werner Keil and others. 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-385, Units of Measurement nor the names of their contributors may be used to 017 * endorse or promote products 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 systems.uom.common; 031 032import static javax.measure.MetricPrefix.MICRO; 033import static tech.units.indriya.unit.Units.*; 034 035import tech.units.indriya.AbstractSystemOfUnits; 036import tech.units.indriya.AbstractUnit; 037import tech.units.indriya.format.SimpleUnitFormat; 038import tech.units.indriya.function.MultiplyConverter; 039import tech.units.indriya.unit.ProductUnit; 040import tech.units.indriya.unit.TransformedUnit; 041 042import javax.measure.Unit; 043import javax.measure.quantity.Angle; 044import javax.measure.quantity.Area; 045 046import javax.measure.quantity.Energy; 047import javax.measure.quantity.Frequency; 048import javax.measure.quantity.Length; 049import javax.measure.quantity.Mass; 050import javax.measure.quantity.Power; 051import javax.measure.quantity.Temperature; 052import javax.measure.quantity.Time; 053import javax.measure.quantity.Speed; 054import javax.measure.quantity.Volume; 055import javax.measure.spi.SystemOfUnits; 056 057import si.uom.quantity.AngularSpeed; 058 059/** 060 * <p> 061 * This class contains units from the United States customary system. 062 * </p> 063 * <p> 064 * 065 * @noextend This class is not intended to be extended by clients. 066 * 067 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 068 * @author <a href="mailto:werner@uom.systems">Werner Keil</a> 069 * @version 2.2, May 21, 2021 070 * @see <a href="http://en.wikipedia.org/wiki/United_States_customary_units"> Wikipedia: United State Customary Units</a> 071 * @see <a href="https://en.wikipedia.org/wiki/Imperial_and_US_customary_measurement_systems"> Wikipedia: United State Customary Units</a> 072 * @since 0.3 073 */ 074public final class USCustomary extends AbstractSystemOfUnits { 075 private static final String SYSTEM_NAME = "United States Customary Units"; 076 077 private static final USCustomary INSTANCE = new USCustomary(); 078 079 /** 080 * Default constructor (prevents this class from being instantiated). 081 */ 082 private USCustomary() { 083 } 084 085 /** 086 * Returns the unique instance of this class. 087 * 088 * @return the USCustomary instance. 089 */ 090 public static SystemOfUnits getInstance() { 091 return INSTANCE; 092 } 093 094 //////////// 095 // Length // 096 //////////// 097 /** 098 * US name for {@link SI#METRE}. 099 */ 100 public static final Unit<Length> METER = addUnit(METRE); 101 102 /** 103 * A unit of length equal to <code>0.3048 m</code> (standard name <code>ft</code>). 104 */ 105 public static final Unit<Length> FOOT = addUnit(METER.multiply(3048).divide(10000), "Foot", "ft"); 106 107 /** 108 * A unit of length equal to <code>1200/3937 m</code> (standard name <code>foot_survey_us</code>). See also: 109 * <a href="http://www.sizes.com/units/foot.htm">foot</a> 110 */ 111 public static final Unit<Length> FOOT_SURVEY = addUnit(METER.multiply(1200).divide(3937), "US Survey foot", "ft_survey_us"); 112 113 /** 114 * A unit of length equal to <code>0.9144 m</code> (standard name <code>yd</code>). 115 */ 116 public static final Unit<Length> YARD = addUnit(FOOT.multiply(3), "Yard", "yd"); 117 118 /** 119 * A unit of length equal to <code>0.0254 m</code> (standard name <code>in</code>). 120 */ 121 public static final Unit<Length> INCH = addUnit(FOOT.divide(12), "in"); 122 123 /** 124 * A unit of length equal to <code>1609.344 m</code> (standard name <code>mi</code>). 125 */ 126 public static final Unit<Length> MILE = addUnit(METER.multiply(1609344).divide(1000), "Mile", "mi"); 127 128 /** 129 * A unit of length equal to the distance that light travels in one year through a vacuum (standard name <code>ly</code>). 130 */ 131 public static final Unit<Length> LIGHT_YEAR = addUnit(METRE.multiply(9.460528405e15), "Light year", "ly"); 132 133 /** 134 * A unit of length equal to <code>1852.0 m</code> (standard name <code>nmi</code>). 135 */ 136 public static final Unit<Length> NAUTICAL_MILE = addUnit(METER.multiply(1852), "Nautical mile", "nmi"); 137 138 ////////// 139 // Mass // 140 ////////// 141 /** 142 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound, standard name <code>lb</code>). 143 */ 144 public static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(45359237).divide(100000000), "Pound", "lb"); // , 145 // Messages.US_lb_name); 146 147 /** 148 * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name <code>oz</code>). 149 */ 150 public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16), "oz"); 151 152 /** 153 * A unit of mass equal to <code>2000 {@link #POUND}</code> (short ton, standard name <code>ton</code>). 154 */ 155 public static final Unit<Mass> TON = addUnit(POUND.multiply(2000), "ton_us"); 156 157 ///////////////// 158 // Temperature // 159 ///////////////// 160 /** 161 * A unit of temperature equal to <code>5/9 °K</code> (standard name <code>°R</code>). 162 */ 163 public static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(9)); 164 165 /** 166 * A unit of temperature equal to degree Rankine minus <code>459.67 °R</code> (standard name <code>°F</code>). 167 * 168 * @see #RANKINE 169 */ 170 public static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE.shift(459.67), "°F"); 171 172 /////////// 173 // Angle // 174 /////////// 175 /** 176 * A unit of angle equal to a full circle or <code>2<i>π</i> 177 * {@link SI#RADIAN}</code> (standard name <code>rev</code>). 178 */ 179 public static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2).multiply(Math.PI).asType(Angle.class), "rev"); 180 181 /** 182 * A unit of angle equal to <code>1/360 {@link #REVOLUTION}</code> (standard name <code>deg</code>). 183 */ 184 public static final Unit<Angle> DEGREE_ANGLE = addUnit(REVOLUTION.divide(360)); 185 186 /** 187 * A unit of angle equal to <code>1/60 {@link #DEGREE_ANGLE}</code> (standard name <code>'</code>). 188 */ 189 public static final Unit<Angle> MINUTE_ANGLE = addUnit(DEGREE_ANGLE.divide(60)); 190 191 /** 192 * A unit of angle equal to <code>1/60 {@link #MINUTE_ANGLE}</code> (standard name <code>"</code>). 193 */ 194 public static final Unit<Angle> SECOND_ANGLE = addUnit(MINUTE_ANGLE.divide(60)); 195 196 /** 197 * A unit of angle equal to <code>0.01 {@link SI#RADIAN}</code> (standard name <code>centiradian</code>). 198 */ 199 public static final Unit<Angle> CENTIRADIAN = addUnit(RADIAN.divide(100)); 200 201 /** 202 * A unit of angle measure equal to <code>1/400 {@link #REVOLUTION}</code> (standard name <code>grade</code> ). 203 */ 204 public static final Unit<Angle> GRADE = addUnit(REVOLUTION.divide(400)); 205 206 ////////////// 207 //Time // 208 ////////////// 209 /** 210 * A unit of time equal to <code>60 s</code> (standard name <code>min</code> ). 211 */ 212 public static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60)); 213 214 /** 215 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard name <code>h</code>). 216 */ 217 public static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60)); 218 219 ////////////// 220 // Speed // 221 ////////////// 222 /** 223 * A unit of velocity expressing the number of {@link #FOOT feet} per {@link SI#SECOND second}. 224 * 225 * @since 0.5.1 226 */ 227 public static final Unit<Speed> FOOT_PER_SECOND = addUnit(FOOT.divide(SECOND).asType(Speed.class)); 228 229 /** 230 * A unit of velocity expressing the number of international {@link #MILE miles} per {@link #HOUR hour} (abbreviation <code>mph</code>). 231 */ 232 public static final Unit<Speed> MILE_PER_HOUR = addUnit(MILE.divide(HOUR).asType(Speed.class), "Mile per hour", "mph"); 233 234 /** 235 * A unit of velocity expressing the number of {@link #NAUTICAL_MILE nautical miles} per {@link #HOUR hour} (abbreviation <code>kn</code>). 236 */ 237 public static final Unit<Speed> KNOT = addUnit(NAUTICAL_MILE.divide(HOUR).asType(Speed.class), "Knot", "kn"); 238 239 ////////// 240 // Area // 241 ////////// 242 /** 243 * A unit of area (standard name <code>sft</code> ). 244 */ 245 public static final Unit<Area> SQUARE_FOOT = addUnit(new ProductUnit<Area>((AbstractUnit<?>) FOOT.multiply(FOOT)), "sft"); 246 247 /** 248 * A unit of area equal to <code>100 m²</code> (standard name <code>a</code> ). 249 */ 250 public static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100), "Are", "a"); 251 252 /** 253 * A unit of area equal to <code>100 {@link #ARE}</code> (standard name <code>ha</code>). 254 */ 255 public static final Unit<Area> HECTARE = addUnit(ARE.multiply(100), "Hectare", "ha"); // Exact. 256 257 /** 258 * The acre is a unit of area used in the imperial and U.S. customary systems. It is equivalent to <code>43,560 square feet</code>. An acre is 259 * about 40% of a <code>HECTARE</code> – slightly smaller than an American football field. (standard name <code>ac</code> ). 260 * 261 * @see <a href="http://en.wikipedia.org/wiki/Acre">Wikipedia: Acre</a> 262 */ 263 public static final Unit<Area> ACRE = addUnit(SQUARE_FOOT.multiply(43560), "Acre", "ac"); 264 265 //////////// 266 // Energy // 267 //////////// 268 /** 269 * A unit of energy equal to one electron-volt (standard name <code>eV</code>, also recognized <code>keV, MeV, GeV</code>). 270 */ 271 public static final Unit<Energy> ELECTRON_VOLT = addUnit(JOULE.multiply(1.602176462e-19), "Electron Volt", "eV"); 272 273 //////////// 274 // Power // 275 //////////// 276 /** 277 * Horsepower (hp) is the name of several units of measurement of power. The most common definitions equal between 735.5 and 750 watts. Horsepower 278 * was originally defined to compare the output of steam engines with the power of draft horses. The unit was widely adopted to measure the output 279 * of piston engines, turbines, electric motors, and other machinery. The definition of the unit varied between geographical regions. Most 280 * countries now use the SI unit watt for measurement of power. With the implementation of the EU Directive 80/181/EEC on January 1, 2010, the use 281 * of horsepower in the EU is only permitted as supplementary unit. 282 */ 283 public static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(745.69987158227), "Horsepower", "hp"); 284 285 /** 286 * Nameplates on electrical motors show their power output, not the power input (the power delivered at the shaft, not the power consumed to drive the motor). <br> 287 * This power output is ordinarily stated in watts or kilowatts. In the United States, the power output is stated in horsepower, which for this purpose is defined as exactly 746 W. 288 */ 289 public static final Unit<Power> ELECTRICAL_HORSEPOWER = addUnit(WATT.multiply(746), "Horsepower (Electrical)", "hp(E)"); 290 291 //////////// 292 // Volume // 293 //////////// 294 /** 295 * A unit of volume equal to one cubic decimeter (default label <code>L</code>, also recognized <code>µL, mL, cL, dL</code>). 296 */ 297 public static final Unit<Volume> LITER = addUnit(new TransformedUnit<Volume>(CUBIC_METRE, MultiplyConverter.ofRational(1, 1000)), "Liter", "L"); 298 299 /** 300 * A unit of volume equal to one cubic inch (<code>in³</code>). 301 */ 302 public static final Unit<Volume> CUBIC_INCH = addUnit(INCH.pow(3).asType(Volume.class), "in³"); 303 304 /** 305 * The cubic foot is an imperial and US customary (non-metric) unit of volume, used in the United States, Canada, and the United Kingdom. It is 306 * defined as the volume of a cube with sides of one foot (0.3048 m) in length. Its volume is 28.3168 liters or about 1⁄35 of a cubic meter. ( 307 * <code>ft³</code>). 308 */ 309 public static final Unit<Volume> CUBIC_FOOT = addUnit(CUBIC_INCH.multiply(1728), "ft³"); 310 311 /** 312 * An acre-foot is a unit of volume commonly used in the United States in reference to large-scale water resources, such as reservoirs, aqueducts, 313 * canals, sewer flow capacity, irrigation water, and river flows. 314 */ 315 public static final Unit<Volume> ACRE_FOOT = addUnit(CUBIC_FOOT.multiply(43560), "Acre-foot", "ac ft"); 316 317 /** 318 * A unit of volume equal to one US dry gallon. (standard name <code>gallon_dry_us</code>). 319 */ 320 public static final Unit<Volume> GALLON_DRY = addUnit(CUBIC_INCH.multiply(2688025).divide(10000), "US dry gallon", "gal_dry_us"); 321 322 /** 323 * A unit of volume equal to one US gallon, Liquid Unit. The U.S. liquid gallon is based on the Queen Anne or Wine gallon occupying 231 cubic 324 * inches (standard name <code>gal</code>). 325 */ 326 public static final Unit<Volume> GALLON_LIQUID = addUnit(CUBIC_INCH.multiply(231), "US gallon", "gal"); 327 328 /** 329 * A unit of volume equal to <code>1 / 128 {@link #GALLON_LIQUID}</code> (standard name <code>oz_fl</code>). 330 */ 331 public static final Unit<Volume> FLUID_OUNCE = addUnit(GALLON_LIQUID.divide(128), "Fluid Ounze", "fl oz"); 332 333 /** 334 * A unit of volume equal to 4 US oz_fl (standard name <code>liq.gi</code>). 335 */ 336 public static final Unit<Volume> GILL_LIQUID = addUnit(FLUID_OUNCE.multiply(4), "Liquid Gill", "liq.gi"); 337 338 /** 339 * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard name <code>min</code>). 340 */ 341 public static final Unit<Volume> MINIM = addUnit(MICRO(LITER).multiply(61.61152d), "Minim", "min_us"); 342 343 /** 344 * A unit of volume equal to <code>60 {@link #MINIM}</code> (standard name <code>fl dr</code>). 345 */ 346 public static final Unit<Volume> FLUID_DRAM = addUnit(MINIM.multiply(60), "Fluid dram", "fl dr"); 347 348 /** 349 * The cup is a unit of measurement for volume, used in cooking to measure liquids (fluid measurement) and bulk foods such as granulated sugar 350 * (dry measurement). A cup is equal to <code>8 {@link #FLUID_OUNCE}</code> (standard name <code>cup</code>). 351 */ 352 public static final Unit<Volume> CUP = addUnit(FLUID_OUNCE.multiply(8), "Cup", "cup"); 353 354 /** 355 * A unit of volume equal to <code>80 {@link #MINIM}</code> (standard name <code>tsp</code>). 356 */ 357 public static final Unit<Volume> TEASPOON = addUnit(MINIM.multiply(80), "Teaspoon", "tsp"); 358 359 /** 360 * A unit of volume equal to <code>3 {@link #TEASPOON}</code> (standard name <code>Tbsp</code>). 361 */ 362 public static final Unit<Volume> TABLESPOON = addUnit(TEASPOON.multiply(3), "Tablespoon", "Tbsp"); 363 364 /** 365 * A unit of volume equal to <code>238.4810 {@link #LITER}</code> (standard name <code>bbl</code>). 366 */ 367 public static final Unit<Volume> BARREL = addUnit(LITER.multiply(238.4810d), "Barrel", "bbl"); 368 369 /** 370 * A unit of volume equal to <code>4 {@link #GILL_LIQUID}</code> (standard name <code>pt</code>). 371 */ 372 public static final Unit<Volume> PINT = addUnit(GILL_LIQUID.multiply(4), "Pint", "pt"); 373 374 375 /////////////////// 376 // Angular Speed // 377 ////////////////// 378 379 /** 380 * Revolutions per minute (abbreviated <code>rpm</code>, RPM, rev/min, r/min, or with the notation min−1) is the number of turns in one minute. It is a unit of rotational speed or the frequency of rotation around a fixed axis. 381 * 382 * @see <a href="https://en.wikipedia.org/wiki/Revolutions_per_minute"> Wikipedia: Revolutions per minute</a> 383 * @since 2.1 384 */ 385 public static final Unit<AngularSpeed> REVOLUTION_PER_MINUTE = addUnit(REVOLUTION.divide(MINUTE), "Pint", "rpm") 386 .asType(AngularSpeed.class); 387 388 @Override 389 public String getName() { 390 return SYSTEM_NAME; 391 } 392 393 /** 394 * Adds a new unit not mapped to any specified quantity type. 395 * 396 * @param unit 397 * the unit being added. 398 * @return <code>unit</code>. 399 */ 400 private static <U extends Unit<?>> U addUnit(U unit) { 401 INSTANCE.units.add(unit); 402 return unit; 403 } 404 405 /** 406 * Adds a new unit not mapped to any specified quantity type and puts a text as symbol or label. 407 * 408 * @param unit 409 * the unit being added. 410 * @param name 411 * the string to use as name 412 * @param text 413 * the string to use as label or symbol 414 * @param isLabel 415 * if the string should be used as a label or not 416 * @return <code>unit</code>. 417 */ 418 private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) { 419 if (isLabel) { 420 SimpleUnitFormat.getInstance().label(unit, text); 421 } 422 if (name != null && unit instanceof AbstractUnit) { 423 return Helper.addUnit(INSTANCE.units, unit, name); 424 } else { 425 INSTANCE.units.add(unit); 426 } 427 return unit; 428 } 429 430 /** 431 * Adds a new unit not mapped to any specified quantity type and puts a text as symbol or label. 432 * 433 * @param unit 434 * the unit being added. 435 * @param name 436 * the string to use as name 437 * @param label 438 * the string to use as label 439 * @return <code>unit</code>. 440 */ 441 private static <U extends Unit<?>> U addUnit(U unit, String name, String label) { 442 return addUnit(unit, name, label, true); 443 } 444 445 /** 446 * Adds a new unit not mapped to any specified quantity type and puts a text as label. 447 * 448 * @param unit 449 * the unit being added. 450 * @param text 451 * the string to use as label or symbol 452 * @return <code>unit</code>. 453 */ 454 private static <U extends Unit<?>> U addUnit(U unit, String text) { 455 return addUnit(unit, null, text, true); 456 } 457}