001/*
002 * Units of Measurement Implementation for Java SE
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,
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 nor the names of its 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 tec.uom.se.quantity.time;
031
032import static tec.uom.se.unit.Units.DAY;
033import static tec.uom.se.unit.Units.HOUR;
034import static tec.uom.se.unit.Units.MINUTE;
035import static tec.uom.se.unit.Units.SECOND;
036
037import java.math.BigDecimal;
038import java.math.MathContext;
039import java.util.Objects;
040import java.util.concurrent.TimeUnit;
041
042import javax.measure.IncommensurableException;
043import javax.measure.Quantity;
044import javax.measure.UnconvertibleException;
045import javax.measure.Unit;
046import javax.measure.UnitConverter;
047import javax.measure.quantity.Time;
048
049import tec.uom.se.AbstractQuantity;
050import tec.uom.se.ComparableQuantity;
051import tec.uom.se.quantity.Quantities;
052
053/**
054 * Class that represents {@link TimeUnit} in Unit-API
055 * 
056 * @author otaviojava
057 * @author keilw
058 * @version 1.0.1
059 * @since 1.0
060 */
061public final class TimeUnitQuantity extends AbstractQuantity<Time> {
062
063  /**
064     * 
065     */
066  private static final long serialVersionUID = -5840251813363744230L;
067
068  private final TimeUnit timeUnit;
069
070  private final Integer value;
071
072  /**
073   * creates the {@link TimeUnitQuantity} using {@link TimeUnit} and {@link Integer}
074   * 
075   * @param timeUnit
076   *          - time to be used
077   * @param value
078   *          - value to be used
079   */
080  TimeUnitQuantity(TimeUnit timeUnit, Integer value) {
081    super(toUnit(timeUnit));
082    this.timeUnit = timeUnit;
083    this.value = value;
084  }
085
086  /**
087   * creates the {@link TimeUnitQuantity} using {@link TimeUnit} and {@link Integer}
088   * 
089   * @param timeUnit
090   *          - time to be used
091   * @param value
092   *          - value to be used
093   * @since 1.0
094   */
095  public static TimeUnitQuantity of(TimeUnit timeUnit, Integer number) {
096    return new TimeUnitQuantity(Objects.requireNonNull(timeUnit), Objects.requireNonNull(number));
097  }
098
099  /**
100   * Creates a {@link TimeUnitQuantity} based a {@link Quantity<Time>} converted to {@link SI#SECOND}.
101   * 
102   * @param quantity
103   *          - quantity to be used
104   * @return the {@link TimeUnitQuantity} converted be quantity in seconds.
105   * @since 1.0
106   */
107  public static TimeUnitQuantity of(Quantity<Time> quantity) {
108    Quantity<Time> seconds = Objects.requireNonNull(quantity).to(SECOND);
109    return new TimeUnitQuantity(TimeUnit.SECONDS, seconds.getValue().intValue());
110  }
111
112  /**
113   * get to {@link TimeUnit}
114   * 
115   * @return the TimeUnit
116   * @since 1.0
117   */
118  public TimeUnit getTimeUnit() {
119    return timeUnit;
120  }
121
122  /**
123   * get value expressed in {@link Integer}
124   * 
125   * @return the value
126   * @since 1.0
127   */
128  public Integer getValue() {
129    return value;
130  }
131
132  /**
133   * converts the {@link TimeUnit} to {@link Unit}
134   * 
135   * @return the {@link TimeUnitQuantity#getTimeUnit()} converted to Unit
136   * @since 1.0
137   */
138  public Unit<Time> toUnit() {
139    return toUnit(timeUnit);
140  }
141
142  /**
143   * Converts the {@link TimeUnitQuantity} to {@link Quantity<Time>}
144   * 
145   * @return this class converted to Quantity
146   * @since 1.0
147   */
148  public Quantity<Time> toQuantity() {
149    return Quantities.getQuantity(value, toUnit());
150  }
151
152  public TimeUnitQuantity to(TimeUnit timeUnit) {
153    Quantity<Time> time = toQuantity().to(toUnit(timeUnit));
154    return new TimeUnitQuantity(timeUnit, time.getValue().intValue());
155  }
156
157  private static Unit<Time> toUnit(TimeUnit timeUnit) {
158    switch (timeUnit) {
159      case MICROSECONDS:
160        return TimeQuantities.MICROSECOND;
161      case MILLISECONDS:
162        return TimeQuantities.MILLISECOND;
163      case NANOSECONDS:
164        return TimeQuantities.NANOSECOND;
165      case SECONDS:
166        return SECOND;
167      case MINUTES:
168        return MINUTE;
169      case HOURS:
170        return HOUR;
171      case DAYS:
172        return DAY;
173      default:
174        throw new IllegalStateException("In TimeUnitQuantity just supports DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, SECONDS ");
175    }
176  }
177
178  /**
179   * @since 1.0
180   */
181  @Override
182  public int hashCode() {
183    return Objects.hash(timeUnit, value);
184  }
185
186  /**
187   * @since 1.0
188   */
189  @Override
190  public boolean equals(Object obj) {
191    if (this == obj) {
192      return true;
193    }
194    if (TimeUnitQuantity.class.isInstance(obj)) {
195      TimeUnitQuantity other = TimeUnitQuantity.class.cast(obj);
196      return Objects.equals(timeUnit, other.timeUnit) && Objects.equals(value, other.value);
197    }
198    if (obj instanceof Quantity<?>) {
199      Quantity<?> that = (Quantity<?>) obj;
200      return Objects.equals(getUnit(), that.getUnit()) && Equalizer.hasEquality(value, that.getValue());
201    }
202    return super.equals(obj);
203  }
204
205  @Override
206  public String toString() {
207    return "Time unit:" + timeUnit + " value: " + value;
208  }
209
210  /**
211   * @since 1.0.1
212   */
213  @Override
214  public ComparableQuantity<Time> add(Quantity<Time> that) {
215    if (getUnit().equals(that.getUnit())) {
216      return TimeQuantities.getQuantity(value + that.getValue().intValue(), timeUnit);
217    }
218    Quantity<Time> converted = that.to(getUnit());
219    return TimeQuantities.getQuantity(value + converted.getValue().intValue(), timeUnit);
220  }
221
222  /**
223   * @since 1.0.1
224   */
225  @Override
226  public ComparableQuantity<Time> subtract(Quantity<Time> that) {
227    if (getUnit().equals(that.getUnit())) {
228      return TimeQuantities.getQuantity(value - that.getValue().intValue(), timeUnit);
229    }
230    Quantity<Time> converted = that.to(getUnit());
231    return TimeQuantities.getQuantity(value - converted.getValue().intValue(), timeUnit);
232  }
233
234  /**
235   * @since 1.0.1
236   */
237  @Override
238  public ComparableQuantity<?> divide(Quantity<?> that) {
239    if (getUnit().equals(that.getUnit())) {
240      return TimeQuantities.getQuantity(value / that.getValue().intValue(), timeUnit);
241    }
242    Unit<?> divUnit = getUnit().divide(that.getUnit());
243    UnitConverter conv;
244    try {
245      conv = getUnit().getConverterToAny(divUnit);
246      return TimeQuantities.getQuantity(value / conv.convert(that.getValue()).intValue(), timeUnit);
247    } catch (UnconvertibleException e) {
248      // TODO Auto-generated catch block
249      e.printStackTrace();
250      return TimeQuantities.getQuantity(value / that.getValue().intValue(), timeUnit);
251    } catch (IncommensurableException e) {
252      // TODO Auto-generated catch block
253      e.printStackTrace();
254      return TimeQuantities.getQuantity(value / that.getValue().intValue(), timeUnit);
255    }
256  }
257
258  /**
259   * @since 1.0.1
260   */
261  @Override
262  public ComparableQuantity<Time> divide(Number that) {
263    return TimeQuantities.getQuantity(value / that.intValue(), timeUnit);
264  }
265
266  /**
267   * @since 1.0.1
268   */
269  @Override
270  public ComparableQuantity<?> multiply(Quantity<?> multiplier) {
271    if (getUnit().equals(multiplier.getUnit())) {
272      return TimeQuantities.getQuantity(value * multiplier.getValue().intValue(), timeUnit);
273    }
274    Unit<?> mulUnit = getUnit().multiply(multiplier.getUnit());
275    UnitConverter conv;
276    try {
277      conv = getUnit().getConverterToAny(mulUnit);
278      return TimeQuantities.getQuantity(value * conv.convert(multiplier.getValue()).intValue(), timeUnit);
279    } catch (UnconvertibleException e) {
280      // TODO Auto-generated catch block
281      e.printStackTrace();
282      return TimeQuantities.getQuantity(value * multiplier.getValue().intValue(), timeUnit);
283    } catch (IncommensurableException e) {
284      // TODO Auto-generated catch block
285      e.printStackTrace();
286      return TimeQuantities.getQuantity(value * multiplier.getValue().intValue(), timeUnit);
287    }
288  }
289
290  /**
291   * @since 1.0.1
292   */
293  @Override
294  public ComparableQuantity<Time> multiply(Number multiplier) {
295    return TimeQuantities.getQuantity(value * multiplier.intValue(), timeUnit);
296  }
297
298  /**
299   * @since 1.0.1
300   */
301  @Override
302  public ComparableQuantity<?> inverse() {
303    return TimeQuantities.getQuantity(1 / value, timeUnit);
304  }
305
306  /**
307   * @since 1.0.1
308   */
309  @Override
310  public boolean isBig() {
311    return false;
312  }
313
314  /**
315   * @since 1.0.1
316   */
317  @Override
318  public BigDecimal decimalValue(Unit<Time> unit, MathContext ctx) throws ArithmeticException {
319    return BigDecimal.valueOf(value.doubleValue());
320  }
321
322  /**
323   * @since 1.0.1
324   */
325  @Override
326  public double doubleValue(Unit<Time> unit) throws ArithmeticException {
327    return value.doubleValue();
328  }
329}