001/*
002 *  Unit-API - Units of Measurement API for Java
003 *  Copyright (c) 2005-2015, 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 nor the names of its 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 si.uom.SI.*;
030import tec.uom.se.AbstractSystemOfUnits;
031import tec.uom.se.AbstractUnit;
032import tec.uom.se.format.SimpleUnitFormat;
033import tec.uom.se.function.RationalConverter;
034import tec.uom.se.unit.ProductUnit;
035import tec.uom.se.unit.TransformedUnit;
036
037import javax.measure.Unit;
038import javax.measure.quantity.Angle;
039import javax.measure.quantity.Area;
040
041import systems.uom.quantity.*;
042
043import javax.measure.quantity.Energy;
044import javax.measure.quantity.Length;
045import javax.measure.quantity.Mass;
046import javax.measure.quantity.Power;
047import javax.measure.quantity.Temperature;
048import javax.measure.quantity.Time;
049import javax.measure.quantity.Speed;
050import javax.measure.quantity.Volume;
051import javax.measure.spi.SystemOfUnits;
052
053/**
054 * <p>
055 * This class contains units from the United States customary system.
056 * </p>
057 * <p>
058 * 
059 * @noextend This class is not intended to be extended by clients.
060 * 
061 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
062 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
063 * @version 1.21, $Date: 2016-05-01 $
064 * @see <a
065 *      href="http://en.wikipedia.org/wiki/United_States_customary_units">Wikipedia:
066 *      United State Customary Units</a>
067 */
068public final class USCustomary extends AbstractSystemOfUnits {
069    private static final String SYSTEM_NAME = "United State Customary Units";
070
071    /**
072     * Default constructor (prevents this class from being instantiated).
073     */
074    private USCustomary() {
075    }
076
077    /**
078     * Returns the unique instance of this class.
079     * 
080     * @return the USCustomary instance.
081     */
082    public static SystemOfUnits getInstance() {
083        return INSTANCE;
084    }
085
086    private static final USCustomary INSTANCE = new USCustomary();
087
088    // //////////
089    // Length //
090    // //////////
091    /**
092     * US name for {@link SI#METRE}.
093     */
094    public static final Unit<Length> METER = METRE;
095
096    /**
097     * A unit of length equal to <code>0.3048 m</code> (standard name
098     * <code>ft</code>).
099     */
100    public static final Unit<Length> FOOT = addUnit(METER.multiply(3048)
101            .divide(10000));
102
103    /**
104     * A unit of length equal to <code>1200/3937 m</code> (standard name
105     * <code>foot_survey_us</code>). See also: <a
106     * href="http://www.sizes.com/units/foot.htm">foot</a>
107     */
108    public static final Unit<Length> FOOT_SURVEY = addUnit(METER.multiply(1200)
109            .divide(3937));
110
111    /**
112     * A unit of length equal to <code>0.9144 m</code> (standard name
113     * <code>yd</code>).
114     */
115    public static final Unit<Length> YARD = addUnit(FOOT.multiply(3));
116
117    /**
118     * A unit of length equal to <code>0.0254 m</code> (standard name
119     * <code>in</code>).
120     */
121    public static final Unit<Length> INCH = addUnit(FOOT.divide(12));
122
123    /**
124     * A unit of length equal to <code>1609.344 m</code> (standard name
125     * <code>mi</code>).
126     */
127    public static final Unit<Length> MILE = addUnit(METER.multiply(1609344)
128            .divide(1000));
129
130    /**
131     * A unit of length equal to the distance that light travels in one year
132     * through a vacuum (standard name <code>ly</code>).
133     */
134    public static final Unit<Length> LIGHT_YEAR = addUnit(METRE
135            .multiply(9.460528405e15));
136
137    /**
138     * A unit of length equal to <code>1852.0 m</code> (standard name
139     * <code>nmi</code>).
140     */
141    public static final Unit<Length> NAUTICAL_MILE = addUnit(METER
142            .multiply(1852));
143
144    /**
145     * A unit of length equal to <code>0.013837 {@link #INCH}</code> exactly
146     * (standard name <code>pt</code>).
147     * 
148     * @see #PIXEL
149     */
150    static final Unit<Length> POINT = addUnit(INCH.multiply(13837).divide(
151            1000000));
152
153    /**
154     * A unit of length equal to <code>1/72 {@link #INCH}</code> (standard name
155     * <code>pixel</code>). It is the American point rounded to an even 1/72
156     * inch.
157     * 
158     * @see #POINT
159     */
160    static final Unit<Length> PIXEL = addUnit(INCH.divide(72));
161
162    // ////////
163    // Mass //
164    // ////////
165
166    /**
167     * A unit of mass equal to <code>453.59237 grams</code> (avoirdupois pound,
168     * standard name <code>lb</code>).
169     */
170    public static final Unit<Mass> POUND = addUnit(KILOGRAM.multiply(45359237)
171            .divide(100000000)); // , Messages.US_lb_name);
172
173    /**
174     * A unit of mass equal to <code>1 / 16 {@link #POUND}</code> (standard name
175     * <code>oz</code>).
176     */
177    public static final Unit<Mass> OUNCE = addUnit(POUND.divide(16));
178
179    /**
180     * A unit of mass equal to <code>2000 {@link #POUND}</code> (short ton,
181     * standard name <code>ton</code>).
182     */
183    public static final Unit<Mass> TON = addUnit(POUND.multiply(2000));
184
185    // ///////////////
186    // Temperature //
187    // ///////////////
188
189    /**
190     * A unit of temperature equal to <code>5/9 °K</code> (standard name
191     * <code>°R</code>).
192     */
193    public static final Unit<Temperature> RANKINE = addUnit(KELVIN.multiply(5)
194            .divide(9));
195
196    /**
197     * A unit of temperature equal to degree Rankine minus
198     * <code>459.67 °R</code> (standard name <code>°F</code>).
199     * 
200     * @see #RANKINE
201     */
202    public static final Unit<Temperature> FAHRENHEIT = addUnit(RANKINE
203            .shift(459.67));
204
205    // /////////
206    // Angle //
207    // /////////
208
209    /**
210     * A unit of angle equal to a full circle or <code>2<i>&pi;</i>
211     * {@link SI#RADIAN}</code> (standard name <code>rev</code>).
212     */
213    public static final Unit<Angle> REVOLUTION = addUnit(RADIAN.multiply(2)
214            .multiply(Math.PI).asType(Angle.class));
215
216    /**
217     * A unit of angle equal to <code>1/360 {@link #REVOLUTION}</code> (standard
218     * name <code>deg</code>).
219     */
220    public static final Unit<Angle> DEGREE_ANGLE = addUnit(REVOLUTION
221            .divide(360));
222
223    /**
224     * A unit of angle equal to <code>1/60 {@link #DEGREE_ANGLE}</code>
225     * (standard name <code>'</code>).
226     */
227    public static final Unit<Angle> MINUTE_ANGLE = addUnit(DEGREE_ANGLE
228            .divide(60));
229
230    /**
231     * A unit of angle equal to <code>1/60 {@link #MINUTE_ANGLE}</code>
232     * (standard name <code>"</code>).
233     */
234    public static final Unit<Angle> SECOND_ANGLE = addUnit(MINUTE_ANGLE
235            .divide(60));
236
237    /**
238     * A unit of angle equal to <code>0.01 {@link SI#RADIAN}</code> (standard
239     * name <code>centiradian</code>).
240     */
241    public static final Unit<Angle> CENTIRADIAN = addUnit(RADIAN.divide(100));
242
243    /**
244     * A unit of angle measure equal to <code>1/400 {@link #REVOLUTION}</code>
245     * (standard name <code>grade</code> ).
246     */
247    public static final Unit<Angle> GRADE = addUnit(REVOLUTION.divide(400));
248
249    // ////////////
250    // TimeUnit //
251    // ////////////
252    /**
253     * A unit of time equal to <code>60 s</code> (standard name <code>min</code>
254     * ).
255     */
256    public static final Unit<Time> MINUTE = addUnit(SECOND.multiply(60));
257
258    /**
259     * A unit of duration equal to <code>60 {@link #MINUTE}</code> (standard
260     * name <code>h</code>).
261     */
262    public static final Unit<Time> HOUR = addUnit(MINUTE.multiply(60));
263
264    // ////////////
265    // Speed //
266    // ////////////
267    /**
268     * A unit of velocity expressing the number of {@link #FOOT feet} per
269     * {@link SI#SECOND second}.
270     */
271    public static final Unit<Speed> FEET_PER_SECOND = addUnit(
272            FOOT.divide(SECOND)).asType(Speed.class);
273
274    /**
275     * A unit of velocity expressing the number of international {@link #MILE
276     * miles} per {@link #HOUR hour} (abbreviation <code>mph</code>).
277     */
278    public static final Unit<Speed> MILES_PER_HOUR = addUnit(MILE.divide(HOUR))
279            .asType(Speed.class);
280
281    /**
282     * A unit of velocity expressing the number of {@link #NAUTICAL_MILE
283     * nautical miles} per {@link #HOUR hour} (abbreviation <code>kn</code>).
284     */
285    public static final Unit<Speed> KNOT = addUnit(NAUTICAL_MILE.divide(HOUR))
286            .asType(Speed.class);
287
288    // ////////
289    // Area //
290    // ////////
291
292    /**
293     * A unit of area (standard name <code>sft</code> ).
294     */
295    public static final Unit<Area> SQUARE_FOOT = addUnit(new ProductUnit<Area>(
296            (AbstractUnit<?>) FOOT.multiply(FOOT)));
297
298    /**
299     * A unit of area equal to <code>100 m²</code> (standard name <code>a</code>
300     * ).
301     */
302    public static final Unit<Area> ARE = addUnit(SQUARE_METRE.multiply(100));
303
304    /**
305     * A unit of area equal to <code>100 {@link #ARE}</code> (standard name
306     * <code>ha</code>).
307     */
308    public static final Unit<Area> HECTARE = addUnit(ARE.multiply(100)); // Exact.
309
310    /**
311     * The acre is a unit of area used in the imperial and U.S. customary
312     * systems. It is equivalent to <code>43,560 square feet</code>. An acre is
313     * about 40% of a <code>HECTARE</code> – slightly smaller than an American
314     * football field. (standard name <code>ac</code> ).
315     * 
316     * @see <a href="http://en.wikipedia.org/wiki/Acre">Wikipedia: Acre</a>
317     */
318    public static final Unit<Area> ACRE = addUnit(SQUARE_FOOT.multiply(43560));
319
320    // ///////////////
321    // Data Amount //
322    // ///////////////
323
324    /**
325     * The unit for binary information (standard name <code>bit</code>).
326     */
327    public static final Unit<Information> BIT = addUnit(NonSI.BIT);
328
329    /**
330     * A unit of data amount equal to <code>8 {@link SI#BIT}</code> (BinarY
331     * TErm, standard name <code>byte</code>).
332     */
333    public static final Unit<Information> BYTE = addUnit(BIT.multiply(8));
334
335    /**
336     * Equivalent {@link #BYTE}
337     */
338    public static final Unit<Information> OCTET = BYTE;
339
340    // //////////
341    // Energy //
342    // //////////
343
344    /**
345     * A unit of energy equal to one electron-volt (standard name
346     * <code>eV</code>, also recognized <code>keV, MeV, GeV</code>).
347     */
348    public static final Unit<Energy> ELECTRON_VOLT = addUnit(JOULE
349            .multiply(1.602176462e-19));
350
351    // //////////
352    // Power //
353    // //////////
354
355    /**
356     * Horsepower (HP) is the name of several units of measurement of power. The
357     * most common definitions equal between 735.5 and 750 watts. Horsepower was
358     * originally defined to compare the output of steam engines with the power
359     * of draft horses. The unit was widely adopted to measure the output of
360     * piston engines, turbines, electric motors, and other machinery. The
361     * definition of the unit varied between geographical regions. Most
362     * countries now use the SI unit watt for measurement of power. With the
363     * implementation of the EU Directive 80/181/EEC on January 1, 2010, the use
364     * of horsepower in the EU is only permitted as supplementary unit.
365     */
366    public static final Unit<Power> HORSEPOWER = addUnit(WATT.multiply(735.499));
367
368    // //////////
369    // Volume //
370    // //////////
371    /**
372     * A unit of volume equal to one cubic decimeter (default label
373     * <code>L</code>, also recognized <code>µL, mL, cL, dL</code>).
374     */
375    public static final TransformedUnit<Volume> LITER = new TransformedUnit<Volume>(
376            CUBIC_METRE, new RationalConverter(1, 1000));
377
378    /**
379     * A unit of volume equal to one cubic inch (<code>in³</code>).
380     */
381    public static final Unit<Volume> CUBIC_INCH = addUnit(INCH.pow(3).asType(
382            Volume.class));
383
384    /**
385     * A unit of volume equal to one US dry gallon. (standard name
386     * <code>gallon_dry_us</code>).
387     */
388    public static final Unit<Volume> GALLON_DRY = addUnit(CUBIC_INCH.multiply(
389            2688025).divide(10000));
390
391    /**
392     * A unit of volume equal to one US gallon, Liquid Unit. The U.S. liquid
393     * gallon is based on the Queen Anne or Wine gallon occupying 231 cubic
394     * inches (standard name <code>gal</code>).
395     */
396    public static final Unit<Volume> GALLON_LIQUID = addUnit(CUBIC_INCH
397            .multiply(231));
398
399    /**
400     * A unit of volume equal to <code>1 / 128 {@link #GALLON_LIQUID}</code>
401     * (standard name <code>oz_fl</code>).
402     */
403    public static final Unit<Volume> FLUID_OUNCE = addUnit(GALLON_LIQUID
404            .divide(128));
405
406    /**
407     * A unit of volume <code>~ 1 drop or 0.95 grain of water </code> (standard
408     * name <code>min</code>).
409     */
410    public static final Unit<Volume> MINIM = addUnit(MICRO(LITER).multiply(
411            61.61152d));
412
413    /**
414     * A unit of volume equal to <code>60 {@link #MINIM}</code> (standard name
415     * <code>fl dr</code>).
416     */
417    public static final Unit<Volume> FLUID_DRAM = addUnit(MINIM.multiply(60));
418
419    /**
420     * The cup is a unit of measurement for volume, used in cooking to measure
421     * liquids (fluid measurement) and bulk foods such as granulated sugar (dry
422     * measurement). A cup is equal to <code>8 {@link #FLUID_OUNCE}</code>
423     * (standard name <code>cup</code>).
424     */
425    public static final Unit<Volume> CUP = addUnit(FLUID_OUNCE.multiply(8));
426
427    /**
428     * A unit of volume equal to <code>80 {@link #MINIM}</code> (standard name
429     * <code>tsp</code>).
430     */
431    public static final Unit<Volume> TEASPOON = addUnit(MINIM.multiply(80));
432
433    /**
434     * A unit of volume equal to <code>3 {@link #TEASPOON}</code> (standard name
435     * <code>Tbsp</code>).
436     */
437    public static final Unit<Volume> TABLESPOON = addUnit(TEASPOON.multiply(3));
438
439    /**
440     * A unit of volume equal to <code>238.4810 {@link #LITER}</code> (standard
441     * name <code>bbl</code>).
442     */
443    public static final Unit<Volume> BARREL = addUnit(LITER.multiply(238.4810d));
444
445    // //////////////////////////////////////////////////////////////////////////
446    // Label adjustments for US system
447    static {
448        SimpleUnitFormat.getInstance().label(POUND, "lb");
449        SimpleUnitFormat.getInstance().label(MILES_PER_HOUR, "mph");
450    }
451
452    /**
453     * Holds the international foot: 0.3048 m exact.
454     */
455    // private static final int INTERNATIONAL_FOOT_DIVIDEND = 3048;
456
457    // private static final int INTERNATIONAL_FOOT_DIViSOR = 10000;
458
459    // /**
460    // * Adds a new unit and maps it to the specified quantity type.
461    // *
462    // * @param unit the unit being added.
463    // * @param type the quantity type.
464    // * @return <code>unit</code>.
465    // */
466    // private static <U extends Unit<?>> U addUnit(U unit, Class<? extends
467    // Quantity<?>> type) {
468    // INSTANCE.units.add(unit);
469    // return unit;
470    // }
471
472    // /**
473    // * Adds a new named unit to the collection.
474    // *
475    // * @param unit the unit being added.
476    // * @param name the name of the unit.
477    // * @return <code>unit</code>.
478    // */
479    // @SuppressWarnings("unchecked")
480    // private static <U extends Unit<?>> U addUnit(U unit, String name) {
481    // if (name != null && unit instanceof Unit) {
482    // Unit<?> aUnit = (Unit<?>)unit;
483    // //aUnit.setName(name);
484    // INSTANCE.units.add(aUnit);
485    // return (U) aUnit;
486    // }
487    // INSTANCE.units.add(unit);
488    // return unit;
489    // }
490
491    /**
492     * Adds a new unit to the collection.
493     * 
494     * @param unit
495     *            the unit being added.
496     * @return <code>unit</code>.
497     */
498    protected static <U extends Unit<?>> U addUnit(U unit) {
499        INSTANCE.units.add(unit);
500        return unit;
501    }
502
503    @Override
504    public String getName() {
505        return SYSTEM_NAME;
506    }
507}