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