001/* 002 * Units of Measurement Systems for Java 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, are permitted provided that the following conditions are met: 008 * 009 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 010 * 011 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 012 * 013 * 3. Neither the name of JSR-363, Units of Measurement nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission. 014 * 015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 017 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 022 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 024 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 025 */ 026package systems.uom.common; 027 028import static tec.uom.se.unit.MetricPrefix.MICRO; 029import static tec.uom.se.unit.Units.*; 030 031import javax.measure.Unit; 032import javax.measure.quantity.Acceleration; 033import javax.measure.quantity.Area; 034import javax.measure.quantity.Force; 035import javax.measure.quantity.Length; 036import javax.measure.quantity.Mass; 037import javax.measure.quantity.Temperature; 038import javax.measure.quantity.Time; 039import javax.measure.quantity.Volume; 040import javax.measure.spi.SystemOfUnits; 041 042import tec.uom.se.AbstractSystemOfUnits; 043import tec.uom.se.AbstractUnit; 044import tec.uom.se.format.SimpleUnitFormat; 045import tec.uom.se.unit.ProductUnit; 046 047/** 048 * <p> 049 * This class contains units from the Imperial system. 050 * </p> 051 * <p> 052 * 053 * @noextend This class is not intended to be extended by clients. 054 * 055 * @author <a href="mailto:units@catmedia.us">Werner Keil</a> 056 * @version 1.0.2, $Date: 2017-03-03 $ 057 * @see <a href= 058 * "http://en.wikipedia.org/wiki/http://en.wikipedia.org/wiki/Imperial_unit"> 059 * Wikipedia: Imperial Units</a> 060 * @see <a href= 061 * "https://en.wikipedia.org/wiki/Imperial_and_US_customary_measurement_systems"> 062 * @since 0.2 063 */ 064public final class Imperial extends AbstractSystemOfUnits { 065 /** 066 * Holds the avoirdupois pound: 0.45359237 kg exact 067 */ 068 static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237; 069 070 static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000; 071 072 /** 073 * Holds the standard gravity constant: 9.80665 m/s² exact. 074 */ 075 private static final int STANDARD_GRAVITY_DIVIDEND = 980665; 076 077 private static final int STANDARD_GRAVITY_DIVISOR = 100000; 078 079 /** 080 * Default constructor (prevents this class from being instantiated). 081 */ 082 private Imperial() { 083 } 084 085 /** 086 * Returns the unique instance of this class. 087 * 088 * @return the Imperial instance. 089 */ 090 public static SystemOfUnits getInstance() { 091 return INSTANCE; 092 } 093 094 private static final Imperial INSTANCE = new Imperial(); 095 096 //////////// 097 // Length // 098 //////////// 099 100 /** 101 * A unit of length equal to <code>0.0254 m</code> (standard name 102 * <code>in</code>). 103 */ 104 public static final Unit<Length> INCH = addUnit(USCustomary.INCH, "Inch", "in"); 105 106 ////////// 107 // Mass // 108 ////////// 109 110 /** 111 * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound, 112 * standard name <code>lb</code>). 113 */ 114 static final Unit<Mass> POUND = addUnit( 115 KILOGRAM.multiply(AVOIRDUPOIS_POUND_DIVIDEND).divide(AVOIRDUPOIS_POUND_DIVISOR), "Pound", "lb", true); 116 /** 117 * An English and imperial unit of weight or mass now equal to 14 118 * avoirdupois pounds or 6.35029318 kg (<code>st</code>). 119 */ 120 public static final Unit<Mass> STONE = addUnit(KILOGRAM.multiply(6.35029318), "st", true); 121 122 /** 123 * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name 124 * <code>oz</code>). 125 */ 126 public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16), "oz"); 127 128 /** 129 * A unit of mass equal to <code>2240 {@link #POUND}</code> (long ton, 130 * standard name <code>ton_uk</code>). 131 */ 132 public static final Unit<Mass> TON_UK = addUnit(POUND.multiply(2240), "ton_uk"); 133 134 /** 135 * A unit of mass equal to <code>1000 kg</code> (metric ton, standard name 136 * <code>t</code>). 137 */ 138 public static final Unit<Mass> METRIC_TON = addUnit(KILOGRAM.multiply(1000), "t"); 139 140 ///////////////// 141 // Temperature // 142 ///////////////// 143 144 /** 145 * A unit of temperature equal to <code>5/9 °K</code> (standard name 146 * <code>°R</code>). 147 */ 148 static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5).divide(9), "°R", true); 149 150 /** 151 * A unit of temperature equal to degree Rankine minus 152 * <code>459.67 °R</code> (standard name <code>°F</code>). 153 * 154 * @see #RANKINE 155 */ 156 static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE.shift(459.67), "°F", true); 157 158 ////////////// 159 // Time // 160 ////////////// 161 /** 162 * A unit of time equal to <code>60 s</code> (standard name <code>min</code> 163 * ). 164 */ 165 static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60)); 166 167 /** 168 * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard 169 * name <code>h</code>). 170 */ 171 static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60)); 172 173 // //////////////// 174 // Acceleration // 175 // //////////////// 176 /** 177 * A unit of acceleration equal to the gravity at the earth's surface 178 * (standard name <code>grav</code>). 179 */ 180 static final Unit<Acceleration> G = addUnit( 181 METRE_PER_SQUARE_SECOND.multiply(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR)); 182 183 ////////// 184 // Area // 185 ////////// 186 187 /** 188 * A unit of area (standard name <code>sft</code> ). 189 */ 190 public static final Unit<Area> SQUARE_FOOT = addUnit(USCustomary.SQUARE_FOOT, "sft", true); 191 192 /** 193 * One acre is 43,560 <code>square feet</code> (standard name <code>a</code> 194 * ). 195 */ 196 public static final Unit<Area> ACRE = addUnit(USCustomary.SQUARE_FOOT.multiply(43560), "Acre", "ac", true); 197 198 //////////// 199 // Volume // 200 //////////// 201 /** 202 * A unit of volume equal to one cubic decimeter (default label 203 * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>). 204 */ 205 static final Unit<Volume> LITRE = addUnit(CUBIC_METRE.divide(1000), "L", true); 206 207 /** 208 * A unit of volume equal to one cubic inch (<code>in³</code>). 209 */ 210 static final Unit<Volume> CUBIC_INCH = addUnit(new ProductUnit<Volume>(USCustomary.INCH.pow(3)), "Cubic Inch", 211 "in³"); 212 213 /** 214 * A unit of volume equal to <code>4.546 09 {@link #LITRE}</code> (standard 215 * name <code>gal_uk</code>). 216 */ 217 public static final Unit<Volume> GALLON_UK = addUnit(LITRE.multiply(454609).divide(100000), "gal_uk"); 218 219 /** 220 * A unit of volume equal to one UK gallon, Liquid Unit. 221 */ 222 // public static final Unit<Volume> GALLON_LIQUID = 223 // addUnit(CUBIC_INCH.multiply(277.42)); 224 225 /** 226 * A unit of volume equal to <code>1 / 160 {@link #GALLON_UK}</code> 227 * (standard name <code>oz_fl_uk</code>). 228 */ 229 static final Unit<Volume> OUNCE_LIQUID_UK = GALLON_UK.divide(160); // , 230 // "oz_fl_uk", 231 // true); 232 233 /** 234 * A unit of volume equal to <code>1 / 160 {@link #GALLON_LIQUID}</code> 235 * (standard name <code>oz_fl</code>). 236 */ 237 public static final Unit<Volume> OUNCE_LIQUID = addUnit(OUNCE_LIQUID_UK, "oz_fl", true); 238 // TODO possible ambiguity if US and Imperial 239 // are registered (try parse) 240 241 /** 242 * A unit of volume equal to <code>5 {@link #OUNCE_LIQUID}</code> (standard 243 * name <code>gi</code>). 244 */ 245 public static final Unit<Volume> GILL = addUnit(OUNCE_LIQUID.multiply(5), "Gill", "gi"); 246 247 /** 248 * A unit of volume equal to <code>20 {@link #OUNCE_LIQUID}</code> (standard 249 * name <code>pt</code>). 250 */ 251 public static final Unit<Volume> PINT = addUnit(OUNCE_LIQUID.multiply(20), "Pint", "pt", true); 252 253 /** 254 * A unit of volume equal to <code>40 {@link #OUNCE_LIQUID}</code> (standard 255 * name <code>qt</code>). 256 */ 257 public static final Unit<Volume> QUART = addUnit(OUNCE_LIQUID.multiply(40), "Quart", "qt"); 258 259 /** 260 * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard 261 * name <code>min</code>). 262 */ 263 public static final Unit<Volume> MINIM = addUnit(MICRO(LITRE).multiply(59.1938802d), "Minim", "min_br"); 264 265 /** 266 * A unit of volume equal to <code>20 {@link #MINIM}</code> (standard name 267 * <code>fl scr</code>). 268 */ 269 public static final Unit<Volume> FLUID_SCRUPLE = addUnit(MINIM.multiply(60), "fl scr", true); 270 271 /** 272 * A unit of volume equal to <code>3 {@link #FLUID_SCRUPLE}</code> (standard 273 * name <code>fl drc</code>). 274 */ 275 public static final Unit<Volume> FLUID_DRACHM = addUnit(FLUID_SCRUPLE.multiply(3), "fl drc", true); 276 277 /** 278 * A unit of force equal to <code>{@link #POUND}·{@link #G}</code> 279 * (standard name <code>lbf</code>). 280 */ 281 static final Unit<Force> POUND_FORCE = addUnit( 282 NEWTON.multiply(1L * AVOIRDUPOIS_POUND_DIVIDEND * STANDARD_GRAVITY_DIVIDEND) 283 .divide(1L * AVOIRDUPOIS_POUND_DIVISOR * STANDARD_GRAVITY_DIVISOR)); 284 /** 285 * A unit of force equal to <code>9.80665 N</code> (standard name 286 * <code>kgf</code>). 287 */ 288 static final Unit<Force> KILOGRAM_FORCE = addUnit( 289 NEWTON.multiply(STANDARD_GRAVITY_DIVIDEND).divide(STANDARD_GRAVITY_DIVISOR)); 290 291 292 /** 293 * Adds a new unit not mapped to any specified quantity type. 294 * 295 * @param unit 296 * the unit being added. 297 * @return <code>unit</code>. 298 */ 299 private static <U extends Unit<?>> U addUnit(U unit) { 300 INSTANCE.units.add(unit); 301 return unit; 302 } 303 304 /** 305 * Adds a new unit not mapped to any specified quantity type and puts a text 306 * as symbol or label. 307 * 308 * @param unit 309 * the unit being added. 310 * @param name 311 * the string to use as name 312 * @param text 313 * the string to use as label or symbol 314 * @param isLabel 315 * if the string should be used as a label or not 316 * @return <code>unit</code>. 317 */ 318 private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) { 319 if (isLabel) { 320 SimpleUnitFormat.getInstance().label(unit, text); 321 } 322 if (name != null && unit instanceof AbstractUnit) { 323 return Helper.addUnit(INSTANCE.units, unit, name); 324 } else { 325 INSTANCE.units.add(unit); 326 } 327 return unit; 328 } 329 330 /** 331 * Adds a new unit not mapped to any specified quantity type and puts a text 332 * as symbol or label. 333 * 334 * @param unit 335 * the unit being added. 336 * @param name 337 * the string to use as name 338 * @param label 339 * the string to use as label 340 * @return <code>unit</code>. 341 */ 342 private static <U extends Unit<?>> U addUnit(U unit, String name, String label) { 343 return addUnit(unit, name, label, true); 344 } 345 346 /** 347 * Adds a new unit not mapped to any specified quantity type and puts a text 348 * as symbol or label. 349 * 350 * @param unit 351 * the unit being added. 352 * @param text 353 * the string to use as label or symbol 354 * @param isLabel 355 * if the string should be used as a label or not 356 * @return <code>unit</code>. 357 */ 358 private static <U extends Unit<?>> U addUnit(U unit, String text, boolean isLabel) { 359 return addUnit(unit, null, text, isLabel); 360 } 361 362 /** 363 * Adds a new unit not mapped to any specified quantity type and puts a text 364 * as label. 365 * 366 * @param unit 367 * the unit being added. 368 * @param text 369 * the string to use as label or symbol 370 * @return <code>unit</code>. 371 */ 372 private static <U extends Unit<?>> U addUnit(U unit, String text) { 373 return addUnit(unit, null, text, true); 374 } 375 376 // ////////////////////////////////////////////////////////////////////////// 377 // Label adjustments for Imperial system 378 static { 379 SimpleUnitFormat.getInstance().label(FLUID_DRACHM, "fl drc"); 380 SimpleUnitFormat.getInstance().label(FLUID_SCRUPLE, "fl scr"); 381 } 382 383 // /////////////////// 384 // Collection View // 385 // /////////////////// 386 387 @Override 388 public String getName() { 389 return getClass().getSimpleName(); 390 } 391}