From 5ce066cb729dfc11b43c7f13d7a181180976685d Mon Sep 17 00:00:00 2001
From: Meno Hochschild Finally the resulting duration will be normalized such that
* smaller units will be converted to bigger units if possible.
Finally the resulting duration will be normalized such that * smaller units will be converted to bigger units if possible.
* - * @return immutable metric for calculating a duration in clock units + * @return reversible immutable metric for calculating a duration in clock units * @see #in(IsoUnit[]) in(U[]) * @see ClockUnit#HOURS * @see ClockUnit#MINUTES @@ -667,7 +667,7 @@ public static TimeMetricFinally the resulting duration will be normalized such that * smaller units will be converted to bigger units if possible.
* - * @return immutable metric for calculating a duration in week-based years, weeks and days + * @return reversible immutable metric for calculating a duration in week-based years, weeks and days * @see #in(IsoUnit[]) in(U[]) * @see CalendarUnit#weekBasedYears() * @see CalendarUnit#WEEKS @@ -699,7 +699,7 @@ public static TimeMetricAm Ende wird die Darstellung automatisch normalisiert, also kleine * Zeiteinheiten so weit wie möglich in große Einheiten umgerechnet.
* - * @return immutable metric for calculating a duration in week-based years, weeks and days + * @return reversible immutable metric for calculating a duration in week-based years, weeks and days * @see #in(IsoUnit[]) in(U[]) * @see CalendarUnit#weekBasedYears() * @see CalendarUnit#WEEKS @@ -730,7 +730,7 @@ public static TimeMetricMetric on the UTC scale (inclusive leap seconds).
+ *Reversible metric on the UTC scale (inclusive leap seconds).
* *Time points before 1972 are not supported.
* * @since 2.0 */ /*[deutsch] - *Metrik auf der UTC-Skala (inklusive Schaltsekunden).
+ *Umkehrbare Metrik auf der UTC-Skala (inklusive Schaltsekunden).
* *Zeitpunkte vor 1972 werden nicht unterstützt.
* * @since 2.0 */ public static final TimeMetricNote: The THIRD INVARIANCE - * {@code t1.plus(t1.until(t2)).minus(t1.until(t2)).equals(t1) == true} - * is often INVALID. A counter example where this invariance is - * violated is given with following dates: - * {t1, t2} = {[2011-05-31], [2011-07-01]}. But if the additional - * condition is required that the day of month is never after 28th - * of a month then this third invariance can be guaranteed. - * Therefore it is recommended to avoid dates near the end of - * month in addition.
+ *Following condition only holds if either the day-of-month of any involved date is + * smaller than 28 or if a reversible metric is used:
+ * + *Note: Usually the third invariance is NOT valid. A counter example + * is given with following dates: {t1, t2} = {[2011-03-31], [2011-07-01]} => P3M1D (using + * the standard metric) because of [2011-07-01] - P3M1D = [2011-03-30]. Example for using + * a reversible metric:
+ * + *+ * PlainDate d1 = PlainDate.of(2011, 3, 31); + * PlainDate d2 = PlainDate.of(2011, 7, 1); + * + * TimeMetric<CalendarUnit, Duration<CalendarUnit>> metric = + * Duration.inYearsMonthsDays().reversible(); + * Duration<CalendarUnit> duration = + * metric.between(d1, d2); // P2M31D + * Duration<CalendarUnit> invDur = + * metric.between(d2, d1); // -P2M31D + * + * boolean firstInvariance = d1.plus(duration).equals(d2); // true + * boolean secondInvariance = invDur.equals(duration.inverse()); // true + * boolean thirdInvariance = d2.minus(duration).equals(d1); // true + ** *
Furthermore the specified algorithm ensures the second invariance * {@code Duration([t1, t2]) = -Duration([t2, t1])} which expresses - * a physical property of any duration. The second invariance means - * that the sign of a duration can only qualify if the first time point - * is before the second time point or other way around. The sign must - * not qualify the always positive length of a duration itself however.
+ * a physical property of any duration as a directed temporal amount. + * The second invariance means that the sign of a duration can only + * qualify if the first time point is before the second time point or + * other way around. The sign must not qualify the always positive length + * of a duration itself however. *Zu beachten: Allgemein gilt die DRITTE INVARIANZ - * {@code t1.plus(t1.until(t2)).minus(t1.until(t2)).equals(t1) == true} - * NICHT. Ein Gegenbeispiel ist mit {t1, t2} = {[2011-05-31], [2011-07-01]} - * gegeben. Wird aber hier als zusätzliche Randbedingung verlangt, - * daß etwa der Tag des Monats nicht nach dem 28. liegt, dann gilt - * diese Invarianz doch noch. Es wid daher empfohlen, bei der Addition von - * Monaten möglichst Datumsangaben zu vermeiden, die am Ende eines - * Monats liegen.
+ *Die folgende Invarianzbedingung gilt nur, wenn entweder der betroffene + * Tag des Monats in den beteiligten Datumsangaben kleiner als 28 ist oder + * wenn eine umkehrbare Metrik verwendet wird:
+ * + *Note: Gewöhnlich ist die dritte Invarianzbedingung nicht gültig. + * Ein Gegenbeispiel ist mit folgenden Werten gegeben: {t1, t2} = {[2011-03-31], [2011-07-01]} + * => P3M1D (im Fall der Standardmetrik) wegen [2011-07-01] - P3M1D = [2011-03-30]. Beispiel + * zur Verwendung einer umkehrbaren Metrik:
+ * + *+ * PlainDate d1 = PlainDate.of(2011, 3, 31); + * PlainDate d2 = PlainDate.of(2011, 7, 1); + * + * TimeMetric<CalendarUnit, Duration<CalendarUnit>> metric = + * Duration.inYearsMonthsDays().reversible(); + * Duration<CalendarUnit> duration = + * metric.between(d1, d2); // P2M31D + * Duration<CalendarUnit> invDur = + * metric.between(d2, d1); // -P2M31D + * + * boolean firstInvariance = d1.plus(duration).equals(d2); // true + * boolean secondInvariance = invDur.equals(duration.inverse()); // true + * boolean thirdInvariance = d2.minus(duration).equals(d1); // true + ** *
Gleichzeitig hilft der Time4J-Algorithmus die Invarianz * {@code Duration([t1, t2]) = -Duration([t2, t1])} einzuhalten, diff --git a/time4j-android/src/main/java/net/time4j/engine/AbstractMetric.java b/time4j-android/src/main/java/net/time4j/engine/AbstractMetric.java index 6b1f1ba..fcb48ba 100644 --- a/time4j-android/src/main/java/net/time4j/engine/AbstractMetric.java +++ b/time4j-android/src/main/java/net/time4j/engine/AbstractMetric.java @@ -40,6 +40,9 @@ * the duration will be normalized such that small units will be * converted to larger units if possible.
* + *This metric can be changed to a reversible one by calling {@code reversible()} + * (third invariance in {@code AbstractDuration}.
+ * * @param generic type of time unit ({@code ChronoUnit}) * @paramgeneric type of duration result * @author Meno Hochschild @@ -59,18 +62,21 @@ * in der Regel normalisiert, also kleine Zeiteinheiten so weit wie * möglich in große Einheiten umgerechnet.
* + *Diese Metrik kann mittels Aufruf von {@code reversible()} umkehrbar gemacht werden + * (dritte Invarianzbedingung in {@code AbstractDuration}.
+ * * @param generic type of time unit ({@code ChronoUnit}) * @param generic type of duration result
* @author Meno Hochschild
* @see AbstractDuration
*/
-public abstract class AbstractMetric
- >
- implements TimeMetric, Comparator {
+public abstract class AbstractMetric>
+ implements TimeMetric, Comparator {
//~ Statische Felder/Initialisierungen --------------------------------
private static final int MIO = 1000000;
+ private static final double LENGTH_OF_FORTNIGHT = 86400.0 * 14;
//~ Instanzvariablen --------------------------------------------------
@@ -105,9 +111,10 @@ public abstract class AbstractMetric
* @throws IllegalArgumentException if any time unit is given more than
* once or if there is no time unit at all
*/
+ @SafeVarargs
protected AbstractMetric(
- boolean normalizing,
- U... units
+ boolean normalizing,
+ U... units
) {
super();
@@ -120,9 +127,11 @@ protected AbstractMetric(
Collections.sort(list, this);
for (int i = 0, n = list.size(); i < n; i++) {
+ U unit = list.get(i);
+
for (int j = i + 1; j < n; j++) {
- if (list.get(i).equals(list.get(j))) {
- throw new IllegalArgumentException("Duplicate unit: " + list.get(i));
+ if (unit.equals(list.get(j))) {
+ throw new IllegalArgumentException("Duplicate unit: " + unit);
}
}
}
@@ -158,8 +167,19 @@ public int compare(U u1, U u2) {
@Override
public Creates an empty time span. Obtains a modified metric which has reversible characteristics. Usually metrics are not reversible by default. The default implementation throws
+ * an Liefert eine veränderte Metrik mit umkehrbaren Eigenschaften. Normalerweise sind Metriken nicht per se umkehrbar. Die Standardimplementierung
+ * wirft eine UnsupportedOperationException
. Overriding implementations should
+ * document the details of reversal characteristics. UnsupportedOperationException
. Implementierungen, die diese
+ * Methode überschreiben, sollten die Einzelheiten der Umkehrbarkeit einer Metrik
+ * beschreiben.