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