net.time4j.ClockUnit Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------
* Copyright © 2013-2014 Meno Hochschild,
* -----------------------------------------------------------------------
* This file (ClockUnit.java) is part of project Time4J.
*
* Time4J is free software: You can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* Time4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Time4J. If not, see .
* -----------------------------------------------------------------------
*/
package net.time4j;
import net.time4j.base.MathUtils;
import net.time4j.engine.Normalizer;
import net.time4j.engine.TimePoint;
import net.time4j.engine.TimeSpan;
/**
* Represents the most common time units on an ISO-8601-conforming
* analogue clock counting the scale ticks.
*
* @author Meno Hochschild
*/
/*[deutsch]
* Repräsentiert die meistgebrächlichen Zeiteinheiten einer
* ISO-konformen Uhrzeit, entsprechend den Skalenstrichen auf einer
* analogen Uhr.
*
* @author Meno Hochschild
*/
public enum ClockUnit
implements IsoTimeUnit {
//~ Statische Felder/Initialisierungen --------------------------------
/** Time unit "hours" (symbol H) */
/*[deutsch] Zeiteinheit "Stunden" (Symbol H) */
HOURS() {
@Override
public char getSymbol() {
return 'H';
}
@Override
public double getLength() {
return 3600.0;
}
},
/** Time unit "minutes" (symbol M) */
/*[deutsch] Zeiteinheit "Minuten" (Symbol M) */
MINUTES() {
@Override
public char getSymbol() {
return 'M';
}
@Override
public double getLength() {
return 60.0;
}
},
/**
* Time unit "seconds" (symbol S) according to the
* position of the second pointer on an analogue clock.
*
* This unit is NOT the SI-second.
*
* @see SI
*/
/*[deutsch]
* Zeiteinheit "Sekunden" (Symbol S) entsprechend der
* Stellung des Sekundenzeigers auf einer analogen Uhr.
*
* Diese Zeiteinheit ist nicht die SI-Sekunde.
*
* @see SI
*/
SECONDS() {
@Override
public char getSymbol() {
return 'S';
}
@Override
public double getLength() {
return 1.0;
}
},
/** Time unit "milliseconds" (symbol 3) */
/*[deutsch] Zeiteinheit "Millisekunden" (Symbol 3) */
MILLIS() {
@Override
public char getSymbol() {
return '3';
}
@Override
public double getLength() {
return 1.0 / 1000;
}
},
/** Time unit "microseconds" (symbol 6) */
/*[deutsch] Zeiteinheit "Mikrosekunden" (Symbol 6) */
MICROS() {
@Override
public char getSymbol() {
return '6';
}
@Override
public double getLength() {
return 1.0 / 1000000;
}
},
/** Time unit "nanoseconds" (symbol 9) */
/*[deutsch] Zeiteinheit "Nanosekunden" (Symbol 9) */
NANOS() {
@Override
public char getSymbol() {
return '9';
}
@Override
public double getLength() {
return 1.0 / 1000000000;
}
};
// Standard-Umrechnungsfaktoren
private static final long[] FACTORS = {
1L, 60L, 3600L, 3600000L, 3600000000L, 3600000000000L
};
//~ Methoden ----------------------------------------------------------
/**
* Calculates the temporal distance between given wall times
* in this unit.
*
* @param generic type of time point
* @param start starting time
* @param end ending time
* @return duration as count of this unit
*/
/*[deutsch]
* Ermittelt den zeitlichen Abstand zwischen den angegebenen
* Zeitangaben gemessen in dieser Einheit.
*
* @param generic type of time point
* @param start starting time
* @param end ending time
* @return duration as count of this unit
*/
public > long between(
T start,
T end
) {
return start.until(end, this);
}
/**
* Converts the given duration to a temporal amount measured in
* this unit.
*
* Conversions from more precise to less precise units are usually
* associated with a loss of information. For example the conversion
* of 999 milliseconds results to 0 seconds. In reverse,
* the conversion of less precise to more precise units can result in
* a numerical overflow.
*
* Example: In order to convert 44 minutes to milliseconds, the
* expression {@code ClockUnit.MILLIS.convert(44L, ClockUnit.MINUTES)}
* is applied. Note: If hours or minutes are to be converted then
* UTC-leapseconds will be ignored that is a minute has here always
* 60 seconds.
*
* @param sourceDuration amount of duration to be converted
* @param sourceUnit time unit of duration to be converted
* @return converted duration expressed in this unit
* @throws ArithmeticException in case of long overflow
*/
/*[deutsch]
* Konvertiert die angegebene Zeitdauer in einen Betrag gezählt
* in dieser Zeiteinheit.
*
* Konversionen von genaueren zu weniger genauen Zeiteinheiten
* führen im allgemeinen zu Verlusten an Information. Zum Beispiel
* wird die Konversion von 999 Millisekunden 0 Sekunden
* ergeben. Umgekehrt kann die Konversion von groben zu feinen Einheiten
* zu einem Überlauf führen.
*
* Beispiel: Um 44 Minuten zu Millisekunden zu konvertieren, wird der
* Ausdruck {@code ClockUnit.MILLIS.convert(44L, ClockUnit.MINUTES)}
* angewandt. Zu beachten: Sind auch Minuten und Stunden zu konvertieren,
* dann werden UTC-Schaltsekunden nicht berücksichtigt, d.h., eine
* Minute hat hier immer genau 60 Sekunden.
*
* @param sourceDuration amount of duration to be converted
* @param sourceUnit time unit of duration to be converted
* @return converted duration expressed in this unit
* @throws ArithmeticException in case of long overflow
*/
public long convert(
long sourceDuration,
ClockUnit sourceUnit
) {
if (sourceDuration == 0) {
return 0L;
}
int o1 = this.ordinal();
int o2 = sourceUnit.ordinal();
if (o1 == o2) {
return sourceDuration;
} else if (o1 > o2) {
return MathUtils.safeMultiply(
sourceDuration,
FACTORS[o1] / FACTORS[o2]
);
} else {
long factor = FACTORS[o2] / FACTORS[o1];
return (sourceDuration / factor); // possible truncation
}
}
/**
* Converts the given duration to an amount in this unit and performs
* any necessary truncation if needed.
*
* @param duration temporal amount in clock units to be converted
* @return count of this unit representing given duration
* @since 1.2
*/
/*[deutsch]
* Konvertiert die angegebene Dauer zu einer Anzahl von Zeiteinheiten
* dieser Instanz und rundet bei Bedarf.
*
* @param duration temporal amount in clock units to be converted
* @return count of this unit representing given duration
* @since 1.2
*/
public long convert(TimeSpan extends ClockUnit> duration) {
if (duration.isEmpty()) {
return 0;
}
long total = 0;
ClockUnit smallest = null;
for (int i = duration.getTotalLength().size() - 1; i >= 0; i--) {
TimeSpan.Item extends ClockUnit> item =
duration.getTotalLength().get(i);
ClockUnit unit = item.getUnit();
if (smallest == null) {
smallest = unit;
total = item.getAmount();
} else {
total =
MathUtils.safeAdd(
total,
smallest.convert(item.getAmount(), unit));
}
}
if (duration.isNegative()) {
total = MathUtils.safeNegate(total);
}
return this.convert(total, smallest); // possibly lossy
}
/**
* Yields a normalizer which converts a given duration in another
* duration with only this clock unit.
*
* @return normalizer
* @since 1.2
* @see #convert(TimeSpan)
*/
/*[deutsch]
* Liefert einen Normalisierer, der eine Dauer in eine andere Dauer nur mit dieser
* Zeiteinheit konvertiert.
*
* @return normalizer
* @since 1.2
* @see #convert(TimeSpan)
*/
public Normalizer only() {
return ClockNormalizer.ofOnlyMode(this);
}
/**
* Yields a normalizer which converts a given duration in another
* duration with smaller units truncated.
*
* @return normalizer
* @since 3.0
*/
/*[deutsch]
* Liefert einen Normalisierer, der eine Dauer in eine andere Dauer so
* konvertiert, daß Dauerelemente mit kleineren Zeiteinheiten
* abgeschnitten werden.
*
* @return normalizer
* @since 3.0
*/
public Normalizer truncated() {
return ClockNormalizer.ofTruncateMode(this);
}
/**
* Yields a normalizer which converts a given duration in another
* normalized duration with smaller units truncated and this unit rounded.
*
* This normalizer is a combination of {@code Duration.STD_CLOCK_PERIOD},
* {@code truncated()} and a special half-up rounding. Example:
*
*
* Duration<ClockUnit> timePeriod = Duration.ofClockUnits(4, 55, 90);
* System.out.println(timePeriod.with(ClockUnit.MINUTES.rounded()));
* // output: P4H57M
*
*
* @return normalizer
* @since 3.0
* @see Duration#STD_CLOCK_PERIOD
*/
/*[deutsch]
* Liefert einen Normalisierer, der eine Dauer in eine andere normalisierte Dauer so
* konvertiert, daß Dauerelemente mit kleineren Zeiteinheiten abgeschnitten werden
* und diese Zeiteinheit gerundet wird.
*
* Dieser Normalisierer ist eine Kombination aus {@code Duration.STD_CLOCK_PERIOD},
* {@code truncated()} und einer kaufmännischen Rundung. Beispiel:
*
*
* Duration<ClockUnit> timePeriod = Duration.ofClockUnits(4, 55, 90);
* System.out.println(timePeriod.with(ClockUnit.MINUTES.rounded()));
* // Ausgabe: P4H57M
*
*
* @return normalizer
* @since 3.0
* @see Duration#STD_CLOCK_PERIOD
*/
public Normalizer rounded() {
return ClockNormalizer.ofRoundingMode(this);
}
/**
* A wall time unit is never calendrical.
*
* @return {@code false}
*/
/*[deutsch]
* Eine Uhrzeiteinheit ist nicht kalendarisch.
*
* @return {@code false}
*/
@Override
public boolean isCalendrical() {
return false;
}
}