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 javax.measure.Unit; 036import javax.measure.quantity.Area; 037import javax.measure.quantity.Force; 038import javax.measure.quantity.Length; 039import javax.measure.quantity.Mass; 040import javax.measure.quantity.Temperature; 041import javax.measure.quantity.Time; 042import javax.measure.quantity.Volume; 043import javax.measure.spi.SystemOfUnits; 044 045import tech.units.indriya.AbstractSystemOfUnits; 046import tech.units.indriya.AbstractUnit; 047import tech.units.indriya.format.SimpleUnitFormat; 048import tech.units.indriya.unit.ProductUnit; 049 050/** 051 * <p> 052 * This class contains units from the Imperial system. 053 * </p> 054 * <p> 055 * 056 * @noextend This class is not intended to be extended by clients. 057 * 058 * @author <a href="mailto:werner@uom.systems">Werner Keil</a> 059 * @version 1.4, $Date: 2021-03-28 $ 060 * @see <a href="http://en.wikipedia.org/wiki/Imperial_units">Wikipedia: Imperial 061 * Units</a> 062 * @see <a href= 063 * "https://en.wikipedia.org/wiki/Imperial_and_US_customary_measurement_systems"> 064 * @since 0.2 065 */ 066public final class Imperial extends AbstractSystemOfUnits { 067 private static final String SYSTEM_NAME = "Imperial Units"; 068 069 /** 070 * Holds the avoirdupois pound: 0.45359237 kg exact 071 */ 072 private static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237; 073 074 private static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000; 075 076 /** 077 * Holds the standard gravity constant: 9.80665 m/s² exact. 078 */ 079 private static final int STANDARD_GRAVITY_DIVIDEND = 980665; 080 081 private static final int STANDARD_GRAVITY_DIVISOR = 100000; 082 083 private static final Imperial INSTANCE = new Imperial(); 084 085 /** 086 * Default constructor (prevents this class from being instantiated). 087 */ 088 private Imperial() { 089 } 090 091 /** 092 * Returns the unique instance of this class. 093 * 094 * @return the Imperial instance. 095 */ 096 public static SystemOfUnits getInstance() { 097 return INSTANCE; 098 } 099 100 //////////// 101 // Length // 102 //////////// 103 /** 104 * A unit of length equal to <code>0.0254 m</code> (standard name 105 * <code>in</code>). 106 */ 107 public static final Unit<Length> INCH = addUnit(USCustomary.INCH, "Inch", "in"); 108 109 ////////// 110 // Mass // 111 ////////// 112 /** 113 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound, 114 * standard name <code>lb</code>). 115 */ 116 public static final Unit<Mass> POUND = addUnit( 117 KILOGRAM.multiply(AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR), "Pound", "lb", true); 118 // LABEL); 119 /** 120 * An English and imperial unit of weight or mass now equal to 14 121 * avoirdupois pounds or 6.35029318 kg (<code>st</code>). 122 */ 123 public static final Unit<Mass> STONE = addUnit(KILOGRAM.multiply(6.35029318), "st", true); 124 125 /** 126 * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name 127 * <code>oz</code>). 128 */ 129 public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16), "oz"); 130 131 /** 132 * A unit of mass equal to <code>2240 {@link #POUND}</code> (long ton, 133 * standard name <code>ton_uk</code>). 134 */ 135 public static final Unit<Mass> TON_UK = addUnit(POUND.multiply(2240), "ton_uk"); 136 137 /** 138 * A unit of mass equal to <code>1000 kg</code> (metric ton, standard name 139 * <code>t</code>). 140 */ 141 public static final Unit<Mass> METRIC_TON = addUnit(KILOGRAM.multiply(1000), "t"); 142 143 ///////////////// 144 // Temperature // 145 ///////////////// 146 /** 147 * A unit of temperature equal to <code>5/9 °K</code> (standard name 148 * <code>°R</code>). 149 */ 150 static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(9), "°R", true); 151 152 /** 153 * A unit of temperature equal to degree Rankine minus 154 * <code>459.67 °R</code> (standard name <code>°F</code>). 155 * 156 * @see #RANKINE 157 */ 158 static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE.shift(459.67), "°F", true); 159 160 ////////////// 161 // Time // 162 ////////////// 163 /** 164 * A unit of time equal to <code>60 s</code> (standard name <code>min</code> 165 * ). 166 */ 167 static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60)); 168 169 /** 170 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard 171 * name <code>h</code>). 172 */ 173 static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60)); 174 175 ////////// 176 // Area // 177 ////////// 178 /** 179 * A unit of area (standard name <code>sft</code> ). 180 */ 181 public static final Unit<Area> SQUARE_FOOT = addUnit(USCustomary.SQUARE_FOOT, "sft", true); 182 183 /** 184 * One acre is 43,560 <code>square feet</code> (standard name 185 * <code>ac</code> ). 186 */ 187 public static final Unit<Area> ACRE = addUnit(USCustomary.SQUARE_FOOT.multiply(43560), "Acre", "ac", true); 188 189 //////////// 190 // Volume // 191 //////////// 192 /** 193 * A unit of volume equal to one cubic decimeter (default label 194 * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>). 195 */ 196 public static final Unit<Volume> LITRE = addUnit(CUBIC_METRE.divide(1000), "L", true); 197 198 /** 199 * A unit of volume equal to one cubic inch (<code>in³</code>). 200 */ 201 public static final Unit<Volume> CUBIC_INCH = addUnit(new ProductUnit<Volume>(USCustomary.INCH.pow(3)), 202 "Cubic Inch", "in³"); 203 204 /** 205 * A unit of volume equal to <code>4.546 09 {@link #LITRE}</code> (standard 206 * name <code>gal_uk</code>). 207 */ 208 public static final Unit<Volume> GALLON_UK = addUnit(LITRE.multiply(454609).divide(100000), "gal_uk"); 209 210 /** 211 * A unit of volume equal to <code>1 / 160 {@link #GALLON_UK}</code> 212 * (standard name <code>fl_oz_uk</code>). 213 */ 214 static final Unit<Volume> FLUID_OUNCE_UK = GALLON_UK.divide(160); 215 216 /** 217 * A unit of volume equal to <code>1 / 160 {@link #GALLON_LIQUID}</code> 218 * (standard name <code>fl_oz</code>). 219 */ 220 public static final Unit<Volume> FLUID_OUNCE = addUnit(FLUID_OUNCE_UK, "fl_oz", true); 221 222 /** 223 * A unit of volume equal to <code>5 {@link #FLUID_OUNCE}</code> (standard 224 * name <code>gi</code>). 225 */ 226 public static final Unit<Volume> GILL = addUnit(FLUID_OUNCE.multiply(5), "Gill", "gi"); 227 228 /** 229 * A unit of volume equal to <code>20 {@link #FLUID_OUNCE}</code> (standard 230 * name <code>pt</code>). 231 */ 232 public static final Unit<Volume> PINT = addUnit(FLUID_OUNCE.multiply(20), "Pint", "pt", true); 233 234 /** 235 * A unit of volume equal to <code>40 {@link #FLUID_OUNCE}</code> (standard 236 * name <code>qt</code>). 237 */ 238 public static final Unit<Volume> QUART = addUnit(FLUID_OUNCE.multiply(40), "Quart", "qt"); 239 240 /** 241 * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard 242 * name <code>min</code>). 243 */ 244 public static final Unit<Volume> MINIM = addUnit(MICRO(LITRE).multiply(59.1938802d), "Minim", "min_br"); 245 246 /** 247 * A unit of volume equal to <code>20 {@link #MINIM}</code> (standard name 248 * <code>fl scr</code>). 249 */ 250 public static final Unit<Volume> FLUID_SCRUPLE = addUnit(MINIM.multiply(60), "fl scr", true); 251 252 /** 253 * A unit of volume equal to <code>3 {@link #FLUID_SCRUPLE}</code> (standard 254 * name <code>fl drc</code>). 255 */ 256 public static final Unit<Volume> FLUID_DRACHM = addUnit(FLUID_SCRUPLE.multiply(3), "fl drc", true); 257 258 /** 259 * A unit of force equal to <code>{@link #POUND}·{@link #G}</code> 260 * (standard name <code>lbf</code>). 261 */ 262 public static final Unit<Force> POUND_FORCE = addUnit( 263 NEWTON.multiply(1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND) 264 .divide(1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR), "lbf"); 265 /** 266 * A unit of force equal to <code>9.80665 N</code> (standard name 267 * <code>kgf</code>). 268 */ 269 static final Unit<Force> KILOGRAM_FORCE = addUnit( 270 NEWTON.multiply(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR)); 271 272 /** 273 * Adds a new unit not mapped to any specified quantity type. 274 * 275 * @param unit 276 * the unit being added. 277 * @return <code>unit</code>. 278 */ 279 private static <U extends Unit<?>> U addUnit(U unit) { 280 INSTANCE.units.add(unit); 281 return unit; 282 } 283 284 /** 285 * Adds a new unit not mapped to any specified quantity type and puts a text 286 * as symbol or label. 287 * 288 * @param unit 289 * the unit being added. 290 * @param name 291 * the string to use as name 292 * @param text 293 * the string to use as label or symbol 294 * @param isLabel 295 * if the string should be used as a label or not 296 * @return <code>unit</code>. 297 */ 298 private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) { 299 if (isLabel) { 300 SimpleUnitFormat.getInstance().label(unit, text); 301 } 302 if (name != null && unit instanceof AbstractUnit) { 303 return Helper.addUnit(INSTANCE.units, unit, name); 304 } else { 305 INSTANCE.units.add(unit); 306 } 307 return unit; 308 } 309 310 /** 311 * Adds a new unit not mapped to any specified quantity type and puts a text 312 * as symbol or label. 313 * 314 * @param unit 315 * the unit being added. 316 * @param name 317 * the string to use as name 318 * @param label 319 * the string to use as label 320 * @return <code>unit</code>. 321 */ 322 private static <U extends Unit<?>> U addUnit(U unit, String name, String label) { 323 return addUnit(unit, name, label, true); 324 } 325 326 /** 327 * Adds a new unit not mapped to any specified quantity type and puts a text 328 * as symbol or label. 329 * 330 * @param unit 331 * the unit being added. 332 * @param text 333 * the string to use as label or symbol 334 * @param isLabel 335 * if the string should be used as a label or not 336 * @return <code>unit</code>. 337 */ 338 private static <U extends Unit<?>> U addUnit(U unit, String text, boolean isLabel) { 339 return addUnit(unit, null, text, isLabel); 340 } 341 342 /** 343 * Adds a new unit not mapped to any specified quantity type and puts a text 344 * as label. 345 * 346 * @param unit 347 * the unit being added. 348 * @param text 349 * the string to use as label or symbol 350 * @return <code>unit</code>. 351 */ 352 private static <U extends Unit<?>> U addUnit(U unit, String text) { 353 return addUnit(unit, null, text, true); 354 } 355 356 ///////////////////// 357 // Collection View // 358 ///////////////////// 359 360 @Override 361 public String getName() { 362 return SYSTEM_NAME; 363 } 364}