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.SECOND;
033import static tec.uom.se.unit.Units.HOUR;
034import static tec.uom.se.unit.Units.DAY;
035
036import java.time.LocalTime;
037import java.time.temporal.ChronoUnit;
038import java.time.temporal.Temporal;
039import java.time.temporal.TemporalAdjuster;
040import java.time.temporal.TemporalUnit;
041import java.util.Objects;
042import java.util.concurrent.TimeUnit;
043import java.util.function.Supplier;
044
045import javax.measure.Quantity;
046import javax.measure.Unit;
047import javax.measure.quantity.Time;
048
049import tec.uom.se.quantity.Quantities;
050import tec.uom.se.unit.MetricPrefix;
051import tec.uom.se.unit.TransformedUnit;
052
053/**
054 * @author Otavio
055 * @author Werner
056 * @version 1.0
057 * @since 1.0
058 */
059public final class TimeQuantities {
060
061  private TimeQuantities() {
062  }
063
064  // Convenience constants outside the unit system (multiples are not held there)
065
066  public static final Unit<Time> MICROSECOND = new TransformedUnit<>("μs", SECOND, MetricPrefix.MICRO.getConverter());
067
068  public static final TransformedUnit<Time> MILLISECOND = new TransformedUnit<>("ms", SECOND, MetricPrefix.MILLI.getConverter());
069
070  public static final TransformedUnit<Time> NANOSECOND = new TransformedUnit<>("ns", SECOND, MetricPrefix.NANO.getConverter());
071
072  /**
073   * Creates the {@link Quantity<Time>} based in the difference of the two {@link Temporal}
074   * 
075   * @param temporalA
076   *          - First parameter to range, inclusive
077   * @param temporalB
078   *          - second parameter to range, exclusive
079   * @return the Quantity difference based in {@link Units#DAY}.
080   * @throws java.time.temporal.UnsupportedTemporalTypeException
081   *           if some temporal doesn't support {@link ChronoUnit#DAYS}
082   */
083  public static Quantity<Time> getQuantity(Temporal temporalA, Temporal temporalB) {
084    long days = ChronoUnit.DAYS.between(temporalA, temporalB);
085    return Quantities.getQuantity(days, DAY);
086  }
087
088  /**
089   * Creates the {@link Quantity<Time>} based in the difference of the two {@link LocalTime}
090   * 
091   * @param localTimeA
092   *          - First parameter to range, inclusive
093   * @param localTimeB
094   *          - second parameter to range, exclusive
095   * @return the Quantity difference based in {@link Units#HOUR}.
096   * @throws java.time.temporal.UnsupportedTemporalTypeException
097   *           if some temporal doesn't support {@link ChronoUnit#DAYS}
098   */
099  public static Quantity<Time> getQuantity(LocalTime localTimeA, LocalTime localTimeB) {
100    long hours = ChronoUnit.HOURS.between(localTimeA, localTimeB);
101    return Quantities.getQuantity(hours, HOUR);
102  }
103
104  /**
105   * Creates the {@link Quantity<Time>} based in the {@link Temporal} with {@link TemporalAdjuster}
106   * 
107   * @param temporalA
108   *          - temporal
109   * @param supplier
110   *          the adjust @see {@link TemporalAdjuster}
111   * @return The Quantity based in Temporal with TemporalAdjuster in {@link Units#DAY}.
112   * @throws java.time.temporal.UnsupportedTemporalTypeException
113   *           if some temporal doesn't support {@link ChronoUnit#DAYS}
114   */
115  public static Quantity<Time> getQuantity(Temporal temporalA, Supplier<TemporalAdjuster> supplier) {
116    Temporal temporalB = temporalA.with(supplier.get());
117    return getQuantity(temporalA, temporalB);
118  }
119
120  /**
121   * Creates the {@link Quantity<Time>} based in the {@link Temporal} with {@link Supplier<TemporalAdjuster>}
122   * 
123   * @param localTimeA
124   * @see {@link LocalTime}
125   * @param supplier
126   *          he adjust @see {@link TemporalAdjuster}
127   * @return The Quantity based in Temporal with TemporalAdjuster in {@link Units#DAY}.
128   * @throws java.time.temporal.UnsupportedTemporalTypeException
129   *           if some temporal doesn't support {@link ChronoUnit#DAYS}
130   */
131  public static Quantity<Time> getQuantity(LocalTime localTimeA, Supplier<TemporalAdjuster> supplier) {
132    LocalTime localTimeB = localTimeA.with(supplier.get());
133    return getQuantity(localTimeA, localTimeB);
134  }
135
136  /**
137   * creates the {@link TimeUnitQuantity} using {@link TimeUnit} and {@link Integer}
138   * 
139   * @param value
140   *          - value to be used
141   * @param timeUnit
142   *          - time to be used
143   */
144  public static TimeUnitQuantity getQuantity(Integer number, TimeUnit timeUnit) {
145    return new TimeUnitQuantity(Objects.requireNonNull(timeUnit), Objects.requireNonNull(number));
146  }
147
148  /**
149   * creates the {@link TemporalQuantity} using {@link TemporalUnit} and {@link Integer}
150   * 
151   * @param value
152   *          - value to be used
153   * @param timeUnit
154   *          - time to be used
155   */
156  public static TemporalQuantity getQuantity(Integer number, TemporalUnit temporalUnit) {
157    return new TemporalQuantity(Objects.requireNonNull(number), Objects.requireNonNull(temporalUnit));
158  }
159
160  /**
161   * Creates a {@link TimeUnitQuantity} based a {@link Quantity<Time>} converted to {@link Units#SECOND}.
162   * 
163   * @param quantity
164   *          - quantity to be used
165   * @return the {@link TimeUnitQuantity} converted be quantity in seconds.
166   */
167  public static TimeUnitQuantity toTimeUnitSeconds(Quantity<Time> quantity) {
168    Quantity<Time> seconds = Objects.requireNonNull(quantity).to(SECOND);
169    return new TimeUnitQuantity(TimeUnit.SECONDS, seconds.getValue().intValue());
170  }
171
172  /**
173   * Creates a {@link TemporalQuantity} based a {@link Quantity<Time>} converted to {@link Units#SECOND}.
174   * 
175   * @param quantity
176   *          - quantity to be used
177   * @return the {@link TemporalQuantity} converted be quantity in seconds.
178   */
179  public static TemporalQuantity toTemporalSeconds(Quantity<Time> quantity) {
180    Quantity<Time> seconds = Objects.requireNonNull(quantity).to(SECOND);
181    return TemporalQuantity.of(seconds);
182  }
183}