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