All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.time4j.engine.TimeSpan Maven / Gradle / Ivy

There is a newer version: 4.38
Show newest version
/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2015 Meno Hochschild, 
 * -----------------------------------------------------------------------
 * This file (TimeSpan.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.engine;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.List;


/**
 * 

Represents a common time span with an associated sign and * a sequence of time units and related amounts.

* * @param generic type of time unit * @author Meno Hochschild */ /*[deutsch] *

Repräsentiert eine allgemeine vorzeichenbehaftete Zeitspannem * in mehreren Zeiteinheiten mit deren zugeordneten Beträgen.

* * @param generic type of time unit * @author Meno Hochschild */ public interface TimeSpan { //~ Methoden ---------------------------------------------------------- /** *

Yields all containted time span items with amount and unit in * the order from largest to smallest time units.

* * @return unmodifiable list sorted by precision of units in ascending * order where every time unit exists at most once */ /*[deutsch] *

Liefert alle enthaltenen Zeitspannenelemente mit Einheit und Betrag * in der Reihenfolge von den größten zu den kleinsten und * genauesten Zeiteinheiten.

* * @return unmodifiable list sorted by precision of units in ascending * order where every time unit exists at most once */ List> getTotalLength(); /** *

Queries if given time unit is part of this time span.

* *

By default the implementation uses following expression:

* *
     *  for (Item<?> item : getTotalLength()) {
     *      if (item.getUnit().equals(unit)) {
     *          return (item.getAmount() > 0);
     *      }
     *  }
     *  return false;
     * 
* * @param unit time unit to be asked (optional) * @return {@code true} if exists else {@code false} * @see #getPartialAmount(Object) getPartialAmount(U) */ /*[deutsch] *

Ist die angegebene Zeiteinheit in dieser Zeitspanne enthalten?

* *

Standardmäßig entspricht die konkrete * Implementierung folgendem Ausdruck:

* *
     *  for (Item<?> item : getTotalLength()) {
     *      if (item.getUnit().equals(unit)) {
     *          return (item.getAmount() > 0);
     *      }
     *  }
     *  return false;
     * 
* * @param unit time unit to be asked (optional) * @return {@code true} if exists else {@code false} * @see #getPartialAmount(Object) getPartialAmount(U) */ boolean contains(U unit); /** *

Yields the partial amount associated with given time unit.

* *

The method returns {@code 0} if this time span does not contain * given time unit. In order to get the total length/amount of this * time span users have to evaluate the method {@link #getTotalLength()} * instead.

* * @param unit time unit (optional) * @return amount as part of time span ({@code >= 0}) */ /*[deutsch] *

Liefert den Teilbetrag zur angegebenen Einheit als Absolutwert.

* *

Die Methode liefert {@code 0}, wenn die Zeiteinheit nicht enthalten * ist. Um den Gesamtwert der Zeitspanne zu bekommen, ist in der Regel * nicht diese Methode, sondern {@link #getTotalLength()} auszuwerten.

* * @param unit time unit (optional) * @return amount as part of time span ({@code >= 0}) */ long getPartialAmount(U unit); /** *

Queries if this time span is negative.

* *

A negative time span relates to the subtraction of two time * points where first one is after second one. The partial amounts * of every time span are never negative. Hence this attribute is not * associated with the partial amounts but only with the time span * itself.

* *

Note: An empty time span itself is never negative in agreement * with the mathematical relation {@code (-1) * 0 = 0}.

* * @return {@code true} if negative and not empty else {@code false} */ /*[deutsch] *

Ist diese Zeitspanne negativ?

* *

Der Begriff der negativen Zeitspanne bezieht sich auf die Subtraktion * zweier Zeitpunkte, von denen der erste vor dem zweiten liegt. Die * einzelnen Beträge der Zeitspanne sind nie negativ. Dieses Attribut * ist daher nicht mit den einzelnen Beträgen assoziiert, sondern * bezieht sich nur auf die Zeitspanne insgesamt.

* *

Notiz: Eine leere Zeitspanne ist selbst niemals negativ in * Übereinstimmung mit der mathematischen Relation * {@code (-1) * 0 = 0}.

* * @return {@code true} if negative and not empty else {@code false} */ boolean isNegative(); /** *

Queries if this time span is positive.

* *

A time span is positive if it is neither empty nor negative.

* * @return {@code true} if positive and not empty else {@code false} * @see #isEmpty() * @see #isNegative() */ /*[deutsch] *

Ist diese Zeitspanne positiv?

* *

Eine Zeitspanne ist genau dann positiv, wenn sie weder leer noch * negativ ist.

* * @return {@code true} if positive and not empty else {@code false} * @see #isEmpty() * @see #isNegative() */ boolean isPositive(); /** *

Queries if this time span is empty.

* *

Per definition an empty time span has no items with a partial * amount different from {@code 0}.

* * @return {@code true} if empty else {@code false} */ /*[deutsch] *

Liegt eine leere Zeitspanne vor?

* *

Per Definition hat eine leere Zeitspanne keine Elemente mit * einem von {@code 0} verschiedenen Teilbetrag.

* * @return {@code true} if empty else {@code false} */ boolean isEmpty(); /** *

Adds this time span to given time point.

* *

Is equivalent to the expression {@link TimePoint#plus(TimeSpan) * time.plus(this)}. Due to better readability usage of the * {@code TimePoint}-method is recommended. Implementations are * required to document the used algorithm in detailed manner.

* * @param generic type of time point * @param time reference time point to add this time span to * @return new time point as result of addition * @see #subtractFrom(TimePoint) */ /*[deutsch] *

Addiert diese Zeitspanne zum angegebenen Zeitpunkt.

* *

Entspricht dem Ausdruck {@link TimePoint#plus(TimeSpan) * time.plus(this)}. Aus Gründen des besseren Lesestils empfiehlt * sich jedoch meistens die Verwendung der {@code TimePoint}-Methode. * Implementierungen müssen den verwendeten Algorithmus genau * dokumentieren.

* * @param generic type of time point * @param time reference time point to add this time span to * @return new time point as result of addition * @see #subtractFrom(TimePoint) */ > T addTo(T time); /** *

Subtracts this time span from given time point.

* *

Is equivalent to the expression {@link TimePoint#minus(TimeSpan) * time.minus(this)}. Due to better readability usage of the * {@code TimePoint}-method is recommended. Implementations are * required to document the used algorithm in detailed manner.

* * @param generic type of time point * @param time reference time point to subtract this time span from * @return new time point as result of subtraction * @see #addTo(TimePoint) */ /*[deutsch] *

Subtrahiert diese Zeitspanne vom angegebenen Zeitpunkt.

* *

Entspricht dem Ausdruck {@link TimePoint#minus(TimeSpan) * time.minus(this)}. Aus Gründen des besseren Lesestils empfiehlt * sich jedoch meistens die Verwendung der {@code TimePoint}-Methode. * Implementierungen müssen den verwendeten Algorithmus genau * dokumentieren.

* * @param generic type of time point * @param time reference time point to subtract this time span from * @return new time point as result of subtraction * @see #addTo(TimePoint) */ > T subtractFrom(T time); //~ Innere Klassen ---------------------------------------------------- /** *

Represents a single item of a time span which is based on only one * time unit and has a non-negative amount.

* * @param type of time unit * @doctags.concurrency */ /*[deutsch] *

Repräsentiert ein atomares Element einer Zeitspanne, das auf nur * einer Zeiteinheit beruht und einen nicht-negativen Betrag hat.

* * @param type of time unit * @doctags.concurrency */ public static final class Item implements Serializable { //~ Statische Felder/Initialisierungen ---------------------------- private static final long serialVersionUID = 1564804888291509484L; //~ Instanzvariablen ---------------------------------------------- /** * @serial time unit */ /*[deutsch] * @serial Zeiteinheit */ private final U unit; /** * @serial amount associated with a time unit {@code > 0} */ /*[deutsch] * @serial mit der Zeiteinheit assoziierter Betrag {@code > 0} */ private final long amount; //~ Konstruktoren ------------------------------------------------- private Item( long amount, U unit ) { super(); if (unit == null) { throw new NullPointerException("Missing chronological unit."); } else if (amount < 0) { throw new IllegalArgumentException( "Temporal amount must be positive or zero: " + amount); } this.amount = amount; this.unit = unit; } //~ Methoden ------------------------------------------------------ /** *

Creates a new time span item.

* * @param type of time unit * @param amount amount in units {@code >= 0} * @param unit time unit * @return new time span item * @throws IllegalArgumentException if amount is negative */ /*[deutsch] *

Konstruiert ein neues Zeitspannenelement.

* * @param type of time unit * @param amount amount in units {@code >= 0} * @param unit time unit * @return new time span item * @throws IllegalArgumentException if amount is negative */ public static Item of( long amount, U unit ) { return new Item(amount, unit); } /** *

Yields the non-negative amount.

* * @return amount in units ({@code >= 0}) */ /*[deutsch] *

Liefert den nicht-negativen Betrag.

* * @return amount in units ({@code >= 0}) */ public long getAmount() { return this.amount; } /** *

Yields the time unit.

* * @return time unit */ /*[deutsch] *

Liefert die Zeiteinheit.

* * @return time unit */ public U getUnit() { return this.unit; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj instanceof Item) { Item that = Item.class.cast(obj); return ( (this.amount == that.amount) && this.unit.equals(that.unit) ); } else { return false; } } @Override public int hashCode() { int hash = this.unit.hashCode(); hash = 29 * hash + (int) (this.amount ^ (this.amount >>> 32)); return hash; } /** *

Provides a canonical representation in the format * 'P' amount '{' unit '}', for example "P4{YEARS}".

* * @return String */ /*[deutsch] *

Liefert eine kanonische Darstellung im Format * 'P' amount '{' unit '}', zum Beispiel "P4{YEARS}".

* * @return String */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append('P'); sb.append(this.amount); sb.append('{'); sb.append(this.unit); sb.append('}'); return sb.toString(); } /** * @serialData Checks the consistency. * @param in object input stream * @throws InvalidObjectException if the state is inconsistent * @throws ClassNotFoundException */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); if ( (this.unit == null) || (this.amount < 0) ) { throw new InvalidObjectException("Inconsistent state."); } } } }