001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2020, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
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-385, Indriya nor the names of their contributors may be used to endorse or promote products
017 *    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 tech.units.indriya.unit;
031
032import static tech.units.indriya.AbstractUnit.ONE;
033
034import javax.measure.Quantity;
035import javax.measure.Unit;
036import javax.measure.quantity.Acceleration;
037import javax.measure.quantity.AmountOfSubstance;
038import javax.measure.quantity.Angle;
039import javax.measure.quantity.Area;
040import javax.measure.quantity.CatalyticActivity;
041import javax.measure.quantity.Dimensionless;
042import javax.measure.quantity.ElectricCapacitance;
043import javax.measure.quantity.ElectricCharge;
044import javax.measure.quantity.ElectricConductance;
045import javax.measure.quantity.ElectricCurrent;
046import javax.measure.quantity.ElectricInductance;
047import javax.measure.quantity.ElectricPotential;
048import javax.measure.quantity.ElectricResistance;
049import javax.measure.quantity.Energy;
050import javax.measure.quantity.Force;
051import javax.measure.quantity.Frequency;
052import javax.measure.quantity.Illuminance;
053import javax.measure.quantity.Length;
054import javax.measure.quantity.LuminousFlux;
055import javax.measure.quantity.LuminousIntensity;
056import javax.measure.quantity.MagneticFlux;
057import javax.measure.quantity.MagneticFluxDensity;
058import javax.measure.quantity.Mass;
059import javax.measure.quantity.Power;
060import javax.measure.quantity.Pressure;
061import javax.measure.quantity.RadiationDoseAbsorbed;
062import javax.measure.quantity.RadiationDoseEffective;
063import javax.measure.quantity.Radioactivity;
064import javax.measure.quantity.SolidAngle;
065import javax.measure.quantity.Speed;
066import javax.measure.quantity.Temperature;
067import javax.measure.quantity.Time;
068import javax.measure.quantity.Volume;
069import tech.units.indriya.AbstractSystemOfUnits;
070import tech.units.indriya.AbstractUnit;
071import tech.units.indriya.function.AddConverter;
072import tech.units.indriya.function.MultiplyConverter;
073import tech.units.indriya.function.RationalNumber;
074
075/**
076 * <p>
077 * This class defines common units.
078 *
079 * @author <a href="mailto:werner@units.tech">Werner Keil</a>
080 * @author <a href="mailto:thodoris.bais@gmail.com">Thodoris Bais</a>
081 * @version 2.3.1, April 21, 2020
082 * @since 1.0
083 * @see <a href="https://usma.org/detailed-list-of-metric-system-units-symbols-and-prefixes">USMA: Detailed list of metric system units, symbols, and prefixes</a>
084 */
085public class Units extends AbstractSystemOfUnits {
086
087        /** Constructor may only be called by subclasses */
088        protected Units() {
089        }
090
091        /** Singleton instance */
092        private static final Units INSTANCE = new Units();
093
094        /*
095         * (non-Javadoc)
096         * 
097         * @see SystemOfUnits#getName()
098         */
099        @Override
100        public String getName() {
101                return Units.class.getSimpleName();
102        }
103
104        // //////////////
105        // BASE UNITS //
106        // //////////////
107
108        /**
109         * The ampere, symbol A, is the SI unit of electric current. It is defined by
110         * taking the fixed numerical value of the elementary charge e to be 1.602 176
111         * 634 × 10⁻¹⁹ when expressed in the unit C, which is equal to A s, where the
112         * second is defined in terms of ∆νCs.
113         *
114         * This definition implies the exact relation e = 1.602 176 634 × 10⁻¹⁹ A s.
115         * Inverting this relation gives an exact expression for the unit ampere in
116         * terms of the defining constants e and ∆νCs:
117         *
118         * 1 A = (e / 1.602 176 634 × 10⁻¹⁹) s⁻¹
119         *
120         * @implNote SI Base Unit
121         */
122        public static final Unit<ElectricCurrent> AMPERE = addUnit(
123                        new BaseUnit<ElectricCurrent>("A", "Ampere", UnitDimension.ELECTRIC_CURRENT), ElectricCurrent.class);
124
125        /**
126         * The candela, symbol cd, is the SI unit of luminous intensity in a given
127         * direction. It is defined by taking the fixed numerical value of the luminous
128         * efficacy of monochromatic radiation of frequency 540 × 10¹² Hz, Kcd, to be
129         * 683 when expressed in the unit lm W−1, which is equal to cd sr W⁻¹, or cd sr
130         * kg⁻¹ m⁻² s³, where the kilogram, metre and second are defined in terms of h,
131         * c and ∆νCs.
132         *
133         * This definition implies the exact relation Kcd = 683 cd sr kg⁻¹ m⁻² s³ for
134         * monochromatic radiation of frequency ν = 540 × 10¹² Hz. Inverting this
135         * relation gives an exact expression for the candela in terms of the defining
136         * constants Kcd, h and ∆νCs:
137         *
138         * 1 cd = (Kcd / 683) kg m² s⁻³ sr⁻¹
139         *
140         * @see <a href="http://en.wikipedia.org/wiki/Candela"> Wikipedia: Candela</a>
141         *
142         * @implNote SI Base Unit
143         */
144        public static final Unit<LuminousIntensity> CANDELA = addUnit(
145                        new BaseUnit<LuminousIntensity>("cd", "Candela", UnitDimension.LUMINOUS_INTENSITY),
146                        LuminousIntensity.class);
147
148        /**
149         * The kelvin, symbol K, is the SI unit of thermodynamic temperature. It is
150         * defined by taking the fixed numerical value of the Boltzmann constant k to be
151         * 1.380 649 × 10−²³ when expressed in the unit J K⁻¹, which is equal to kg m²
152         * s⁻² K⁻¹, where the kilogram, metre and second are defined in terms of h, c
153         * and ∆νCs.
154         *
155         * This definition implies the exact relation k = 1.380 649 × 10⁻²³ kg m² s⁻²
156         * K⁻¹. Inverting this relation gives an exact expression for the kelvin in
157         * terms of the defining constants k, h and ∆νCs:
158         *
159         * 1 K = (1.380 649 / k) × 10⁻²³ kg m² s⁻²
160         *
161         * @see #JOULE
162         * @implNote SI Base Unit
163         */
164        public static final Unit<Temperature> KELVIN = addUnit(
165                        new BaseUnit<Temperature>("K", "Kelvin", UnitDimension.TEMPERATURE), Temperature.class);
166
167        /**
168         * The kilogram, symbol kg, is the SI unit of mass. It is defined by taking the
169         * fixed numerical value of the Planck constant h to be 6.626 070 15 × 10⁻³⁴
170         * when expressed in the unit J s, which is equal to kg m² s−1, where the metre
171         * and the second are defined in terms of c and ∆νCs.
172         *
173         * This definition implies the exact relation h = 6.626 070 15 × 10−34 kg m²
174         * s⁻¹. Inverting this relation gives an exact expression for the kilogram in
175         * terms of the three defining constants h, ∆νCs and c:
176         *
177         * 1 kg = (h / 6.626 070 15 × 10⁻³⁴) m⁻² s
178         *
179         * @see <a href="https://en.wikipedia.org/wiki/Kilogram">Wikipedia: Kilogram</a>
180         * @see #GRAM
181         * @see #METRE
182         * @see #SECOND
183         *
184         * @implNote SI Base Unit
185         */
186        public static final Unit<Mass> KILOGRAM = addUnit(new BaseUnit<Mass>("kg", "Kilogram", UnitDimension.MASS), Mass.class);
187
188        /**
189         * The metre, symbol m, is the SI unit of length. It is defined by taking the
190         * fixed numerical value of the speed of light in vacuum c to be 299 792 458
191         * when expressed in the unit m s⁻¹, where the second is defined in terms of the
192         * caesium frequency ∆νCs.
193         *
194         * This definition implies the exact relation c = 299 792 458 m s⁻¹. Inverting
195         * this relation gives an exact expression for the metre in terms of the
196         * defining constants c and ∆νCs:
197         *
198         * 1 m = (c / 299 792 458)s = 9 192 631 770 c / 299 792 458 ∆νCs ≈ 30.663 319 c
199         * / ∆νCs
200         *
201         * @implNote SI Base Unit
202         */
203        public static final Unit<Length> METRE = addUnit(new BaseUnit<>("m", "Metre", UnitDimension.LENGTH), Length.class);
204
205        /**
206         * The mole, symbol mol, is the SI unit of amount of substance. One mole
207         * contains exactly 6.022 140 76 × 10²³ elementary entities. This number is the
208         * fixed numerical value of the Avogadro constant, NA, when expressed in the
209         * unit mol⁻¹ and is called the Avogadro number.
210         *
211         * The amount of substance, symbol n, of a system is a measure of the number of
212         * specified elementary entities. An elementary entity may be an atom, a
213         * molecule, an ion, an electron, any other particle or specified group of
214         * particles. This definition implies the exact relation Nₐ = 6.022 140 76 ×
215         * 10²³ mol⁻¹.
216         *
217         * Inverting this relation gives an exact expression for the mole in terms of
218         * the defining constant NA:
219         *
220         * 1 mol = 6.02214076 × 10²³ / Nₐ
221         *
222         * @implNote SI Base Unit
223         */
224        public static final Unit<AmountOfSubstance> MOLE = addUnit(new BaseUnit<>("mol", "Mole", UnitDimension.AMOUNT_OF_SUBSTANCE),
225                        AmountOfSubstance.class);
226
227        /**
228         * The second, symbol s, is the SI unit of time. It is defined by taking the
229         * fixed numerical value of the caesium frequency ∆νCs, the unperturbed
230         * ground-state hyperfine transition frequency of the caesium 133 atom, to be 9
231         * 192 631 770 when expressed in the unit Hz, which is equal to s⁻¹.
232         *
233         * This definition implies the exact relation ∆νCs = 9 192 631 770 Hz. Inverting
234         * this relation gives an expression for the unit second in terms of the
235         * defining constant ∆νCs:
236         *
237         * 1 Hz = ∆νCs / 9 192 631 770 or 1 s = 9 192 631 770 / ∆νCs
238         *
239         * @implNote SI Base Unit
240         */
241        public static final Unit<Time> SECOND = addUnit(new BaseUnit<>("s", "Second", UnitDimension.TIME), Time.class);
242
243        // //////////////////////////////
244        // SI DERIVED ALTERNATE UNITS //
245        // //////////////////////////////
246
247        /**
248         * The SI derived unit for mass quantities (standard name <code>g</code>). The
249         * base unit for mass quantity is {@link #KILOGRAM}.
250         */
251        public static final Unit<Mass> GRAM = addUnit(KILOGRAM.divide(1000));
252        // = new TransformedUnit(KILOGRAM, MetricPrefix.KILO.getConverter());
253
254        /**
255         * The SI unit for plane angle quantities (standard name <code>rad</code>). One
256         * radian is the angle between two radii of a circle such that the length of the
257         * arc between them is equal to the radius.
258         */
259        public static final Unit<Angle> RADIAN = addUnit(AlternateUnit.of(ONE, "rad", "Radian"), Angle.class);
260
261        /**
262         * The SI unit for solid angle quantities (standard name <code>sr</code>). One
263         * steradian is the solid angle subtended at the center of a sphere by an area
264         * on the surface of the sphere that is equal to the radius squared. The total
265         * solid angle of a sphere is 4*Pi steradians.
266         */
267        public static final Unit<SolidAngle> STERADIAN = addUnit(new AlternateUnit<>(ONE, "sr", "Steradian"), SolidAngle.class);
268
269        /**
270         * The SI unit for frequency (standard name <code>Hz</code>). A unit of
271         * frequency equal to one cycle per second. After Heinrich Rudolf Hertz
272         * (1857-1894), German physicist who was the first to produce radio waves
273         * artificially.
274         */
275        public static final Unit<Frequency> HERTZ = addUnit(new AlternateUnit<Frequency>(ONE.divide(SECOND), "Hz", "Hertz"),
276                        Frequency.class);
277
278        /**
279         * The SI unit for force (standard name <code>N</code>). One newton is the force
280         * required to give a mass of 1 kilogram an Force of 1 metre per second per
281         * second. It is named after the English mathematician and physicist Sir Isaac
282         * Newton (1642-1727).
283         */
284        public static final Unit<Force> NEWTON = addUnit(
285                        new AlternateUnit<Force>(METRE.multiply(KILOGRAM).divide(SECOND.pow(2)), "N", "Newton"), Force.class);
286
287        /**
288         * The SI unit for pressure, stress (standard name <code>Pa</code>). One pascal
289         * is equal to one newton per square meter. It is named after the French
290         * philosopher and mathematician Blaise Pascal (1623-1662).
291         */
292        @SuppressWarnings({ "unchecked", "rawtypes" })
293        public static final Unit<Pressure> PASCAL = addUnit(new AlternateUnit(NEWTON.divide(METRE.pow(2)), "Pa", "Pascal"),
294                        Pressure.class);
295
296        /**
297         * The SI unit for energy, work, quantity of heat (<code>J</code>). One joule is
298         * the amount of work done when an applied force of 1 newton moves through a
299         * distance of 1 metre in the direction of the force. It is named after the
300         * English physicist James Prescott Joule (1818-1889).
301         */
302        public static final Unit<Energy> JOULE = addUnit(new AlternateUnit<Energy>(NEWTON.multiply(METRE), "J", "Joule"),
303                        Energy.class);
304
305        /**
306         * The SI unit for power, radiant, flux (standard name <code>W</code>). One watt
307         * is equal to one joule per second. It is named after the British scientist
308         * James Watt (1736-1819).
309         */
310        public static final Unit<Power> WATT = addUnit(new AlternateUnit<Power>(JOULE.divide(SECOND), "W", "Watt"), Power.class);
311
312        /**
313         * The SI unit for electric charge, quantity of electricity (standard name
314         * <code>C</code>). One Coulomb is equal to the quantity of charge transferred
315         * in one second by a steady current of one ampere. It is named after the French
316         * physicist Charles Augustin de Coulomb (1736-1806).
317         */
318        public static final Unit<ElectricCharge> COULOMB = addUnit(
319                        new AlternateUnit<ElectricCharge>(SECOND.multiply(AMPERE), "C", "Coulomb"), ElectricCharge.class);
320
321        /**
322         * The SI unit for electric potential difference, electromotive force (standard
323         * name <code>V</code>). One Volt is equal to the difference of electric
324         * potential between two points on a conducting wire carrying a constant current
325         * of one ampere when the power dissipated between the points is one watt. It is
326         * named after the Italian physicist Count Alessandro Volta (1745-1827).
327         */
328        public static final Unit<ElectricPotential> VOLT = addUnit(
329                        new AlternateUnit<ElectricPotential>(WATT.divide(AMPERE), "V", "Volt"), ElectricPotential.class);
330
331        /**
332         * The SI unit for capacitance (standard name <code>F</code>). One Farad is
333         * equal to the capacitance of a capacitor having an equal and opposite charge
334         * of 1 coulomb on each plate and a potential difference of 1 volt between the
335         * plates. It is named after the British physicist and chemist Michael Faraday
336         * (1791-1867).
337         */
338        public static final Unit<ElectricCapacitance> FARAD = addUnit(
339                        new AlternateUnit<ElectricCapacitance>(COULOMB.divide(VOLT), "F", "Farad"), ElectricCapacitance.class);
340
341        /**
342         * The SI unit for electric resistance (standard name <code>Ohm</code>). One Ohm
343         * is equal to the resistance of a conductor in which a current of one ampere is
344         * produced by a potential of one volt across its terminals. It is named after
345         * the German physicist Georg Simon Ohm (1789-1854).
346         */
347        public static final Unit<ElectricResistance> OHM = addUnit(
348                        new AlternateUnit<ElectricResistance>(VOLT.divide(AMPERE), "Ω", "Ohm"), ElectricResistance.class);
349
350        /**
351         * The SI unit for electric conductance (standard name <code>S</code>). One
352         * Siemens is equal to one ampere per volt. It is named after the German
353         * engineer Ernst Werner von Siemens (1816-1892).
354         */
355        public static final Unit<ElectricConductance> SIEMENS = addUnit(
356                        new AlternateUnit<ElectricConductance>(AMPERE.divide(VOLT), "S", "Siemens"), ElectricConductance.class);
357
358        /**
359         * The SI unit for magnetic flux (standard name <code>Wb</code>). One Weber is
360         * equal to the magnetic flux that in linking a circuit of one turn produces in
361         * it an electromotive force of one volt as it is uniformly reduced to zero
362         * within one second. It is named after the German physicist Wilhelm Eduard
363         * Weber (1804-1891).
364         */
365        public static final Unit<MagneticFlux> WEBER = addUnit(new AlternateUnit<MagneticFlux>(VOLT.multiply(SECOND), "Wb", "Weber"),
366                        MagneticFlux.class);
367
368        /**
369         * The alternate unit for magnetic flux density (standard name <code>T</code>).
370         * One Tesla is equal equal to one weber per square metre. It is named after the
371         * Serbian-born American electrical engineer and physicist Nikola Tesla
372         * (1856-1943).
373         */
374        public static final Unit<MagneticFluxDensity> TESLA = addUnit(
375                        new AlternateUnit<MagneticFluxDensity>(WEBER.divide(METRE.pow(2)), "T", "Tesla"), MagneticFluxDensity.class);
376
377        /**
378         * The alternate unit for inductance (standard name <code>H</code>). One Henry
379         * is equal to the inductance for which an induced electromotive force of one
380         * volt is produced when the current is varied at the rate of one ampere per
381         * second. It is named after the American physicist Joseph Henry (1791-1878).
382         */
383        public static final Unit<ElectricInductance> HENRY = addUnit(
384                        new AlternateUnit<ElectricInductance>(WEBER.divide(AMPERE), "H", "Henry"), ElectricInductance.class);
385
386        /**
387         * The SI unit for Celsius temperature (standard name <code>°C</code>). This is
388         * a unit of temperature such as the freezing point of water (at one atmosphere
389         * of pressure) is 0 °C, while the boiling point is 100 °C.
390         */
391        @SuppressWarnings({ "rawtypes", "unchecked" })
392        public static final Unit<Temperature> CELSIUS = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
393                        new TransformedUnit(KELVIN, new AddConverter(273.15)), "Celsius", "\u2103");
394        // Not mapping to Temperature since temperature is mapped to Kelvin.
395
396        /**
397         * The SI unit for luminous flux (standard name <code>lm</code>). One Lumen is
398         * equal to the amount of light given out through a solid angle by a source of
399         * one candela intensity radiating equally in all directions.
400         */
401        public static final Unit<LuminousFlux> LUMEN = addUnit(
402                        new AlternateUnit<LuminousFlux>(CANDELA.multiply(STERADIAN), "lm", "Lumen"), LuminousFlux.class);
403
404        /**
405         * The SI unit for illuminance (standard name <code>lx</code>). One Lux is equal
406         * to one lumen per square metre.
407         */
408        public static final Unit<Illuminance> LUX = addUnit(
409                        new AlternateUnit<Illuminance>(LUMEN.divide(METRE.pow(2)), "lx", "Lux"), Illuminance.class);
410
411        /**
412         * The SI unit for activity of a radionuclide (standard name <code>Bq</code> ).
413         * One becquerel is the radiation caused by one disintegration per second. It is
414         * named after the French physicist, Antoine-Henri Becquerel (1852-1908).
415         */
416        public static final Unit<Radioactivity> BECQUEREL = addUnit(
417                        new AlternateUnit<Radioactivity>(ONE.divide(SECOND), "Bq", "Becquerel"), Radioactivity.class);
418
419        /**
420         * The SI unit for absorbed dose, specific energy (imparted), kerma (standard
421         * name <code>Gy</code>). One gray is equal to the dose of one joule of energy
422         * absorbed per one kilogram of matter. It is named after the British physician
423         * L. H. Gray (1905-1965).
424         */
425        public static final Unit<RadiationDoseAbsorbed> GRAY = addUnit(
426                        new AlternateUnit<RadiationDoseAbsorbed>(JOULE.divide(KILOGRAM), "Gy", "Gray"), RadiationDoseAbsorbed.class);
427
428        /**
429         * The SI unit for dose equivalent (standard name <code>Sv</code>). One Sievert
430         * is equal is equal to the actual dose, in grays, multiplied by a "quality
431         * factor" which is larger for more dangerous forms of radiation. It is named
432         * after the Swedish physicist Rolf Sievert (1898-1966).
433         */
434        public static final Unit<RadiationDoseEffective> SIEVERT = addUnit(
435                        new AlternateUnit<RadiationDoseEffective>(JOULE.divide(KILOGRAM), "Sv", "Sievert"), RadiationDoseEffective.class);
436
437        /**
438         * The SI unit for catalytic activity (standard name <code>kat</code>).
439         */
440        public static final Unit<CatalyticActivity> KATAL = addUnit(
441                        new AlternateUnit<CatalyticActivity>(MOLE.divide(SECOND), "kat", "Katal"), CatalyticActivity.class);
442
443        //////////////////////////////
444        // SI DERIVED PRODUCT UNITS //
445        //////////////////////////////
446
447        /**
448         * The SI unit for velocity quantities (standard name <code>m/s</code>).
449         */
450        public static final Unit<Speed> METRE_PER_SECOND = addUnit(new ProductUnit<>(METRE.divide(SECOND)), Speed.class);
451
452        /**
453         * The SI unit for acceleration quantities (standard name <code>m/s2</code> ).
454         */
455        public static final Unit<Acceleration> METRE_PER_SQUARE_SECOND = addUnit(
456                        new ProductUnit<>(METRE_PER_SECOND.divide(SECOND)), Acceleration.class);
457
458        /**
459         * The SI unit for area quantities (standard name <code>m2</code>).
460         */
461        public static final Unit<Area> SQUARE_METRE = addUnit(new ProductUnit<>(METRE.multiply(METRE)), Area.class);
462
463        /**
464         * The SI unit for volume quantities (standard name <code>m3</code>).
465         */
466        public static final Unit<Volume> CUBIC_METRE = addUnit(new ProductUnit<Volume>(SQUARE_METRE.multiply(METRE)),
467                        Volume.class);
468
469        /**
470         * A unit of velocity expressing the number of international {@link #KILOMETRE
471         * kilometres} per {@link #HOUR hour} (abbreviation <code>km/h</code>).
472         * 
473         * @see <a href="https://en.wikipedia.org/wiki/Kilometres_per_hour"> Wikipedia: Kilometres per hour</a>
474         */
475        public static final Unit<Speed> KILOMETRE_PER_HOUR = addUnit(METRE_PER_SECOND.multiply(RationalNumber.of(5, 18)))
476                        .asType(Speed.class);
477
478        /////////////////////////////////////////////////////////////////
479        // Common Units outside the SI that are accepted for use with the SI. //
480        /////////////////////////////////////////////////////////////////
481
482        /**
483         * A dimensionless unit accepted for use with SI units (standard name
484         * <code>%</code>).
485         */
486        public static final Unit<Dimensionless> PERCENT = addUnit(
487                        new TransformedUnit<>("%", "Percent", ONE, MultiplyConverter.ofRational(1, 100)));
488
489        //////////
490        // Time //
491        //////////
492        /**
493         * A time unit accepted for use with SI units (standard name <code>min</code>).
494         */
495        public static final Unit<Time> MINUTE = addUnit(
496                        new TransformedUnit<>("min", "Minute", SECOND, SECOND, MultiplyConverter.ofRational(60, 1)));
497
498        /**
499         * A time unit accepted for use with SI units (standard name <code>h</code> ).
500         */
501        public static final Unit<Time> HOUR = addUnit(
502                        new TransformedUnit<>("h", "Hour", SECOND, SECOND, MultiplyConverter.ofRational(60 * 60, 1)));
503
504        /**
505         * A time unit accepted for use with SI units (standard name <code>d</code> ).
506         */
507        public static final Unit<Time> DAY = addUnit(
508                        new TransformedUnit<>("d", "Day", SECOND, SECOND, MultiplyConverter.ofRational(24 * 60 * 60, 1)));
509
510        /**
511         * A unit of duration equal to 7 {@link #DAY} (standard name <code>wk</code>).
512         */
513        public static final Unit<Time> WEEK = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
514                        DAY.multiply(7), "Week", "wk");
515
516        /**
517         * A time unit accepted for use with SI units (standard name <code>y</code> ).
518         */
519        public static final Unit<Time> YEAR = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units,
520                        Units.DAY.multiply(365.2425), "Year", "y");
521
522        /**
523         * A unit of duration equal to 1/12 {@link #YEAR} (standard name <code>mon</code>).
524         * @since 2.3
525         */
526        public static final Unit<Time> MONTH = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
527                        YEAR.divide(12), "Month", "mon");
528        
529        /**
530         * A volume unit accepted for use with SI units (standard name <code>l</code>).
531         *
532         * @see <a href="https://en.wikipedia.org/wiki/Litre"> Wikipedia: Litre</a>
533         */
534        public static final Unit<Volume> LITRE = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units,
535                        new TransformedUnit<Volume>(CUBIC_METRE, MultiplyConverter.ofRational(1, 1000)), "Litre", "l");
536
537        /**
538         * Returns the unique instance of this class.
539         *
540         * @return the Units instance.
541         */
542        public static Units getInstance() {
543                return INSTANCE;
544        }
545
546        static {
547                // have to add AbstractUnit.ONE as Dimensionless, too
548                addUnit(ONE);
549                INSTANCE.quantityToUnit.put(Dimensionless.class, ONE);
550        }
551
552        /**
553         * Adds a new unit not mapped to any specified quantity type.
554         *
555         * @param unit the unit being added.
556         * @return <code>unit</code>.
557         */
558        private static <U extends Unit<?>> U addUnit(U unit) {
559                INSTANCE.units.add(unit);
560                return unit;
561        }
562
563        /**
564         * Adds a new unit and maps it to the specified quantity type.
565         *
566         * @param unit the unit being added.
567         * @param type the quantity type.
568         * @return <code>unit</code>.
569         */
570        private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) {
571                INSTANCE.units.add(unit);
572                INSTANCE.quantityToUnit.put(type, unit);
573                return unit;
574        }
575}