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

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

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


/**
 * 

Represents an immutable calendar variant.

* *

Display and change chronological element values

* *

The calendar variant consists of chronological elements. This base class * delegates the element and time arithmetic to the associated calendar family respective to * the underlying rules of elements and units. However, any concrete subclass * is required to define the state and reflect it in all {@code get()}-methods * and also to specify the serialization behaviour.

* *

Element values can only be changed by creating a new immutable copy * of the original instance. This is done via all {@code with()}-methods.

* *

Calendar system

* *

Every calendar variant is a member of a calendar family. That means referring to * a calendar system via a variant name. Hence a limited day arithmetic using the * class {@code CalendarDays} is always possible.

* *

Sorting

* *

The sorting algorithm prefers the temporal order then the lexicographical comparison * based on variant names. In case of doubt the documentation of the subclass is leading. * Alternatively, the interface {@code Temporal} can be used to enable a pure temporal order.

* *

Implementation notes

* *
    *
  • All subclasses must be final und immutable.
  • *
  • Documentation of supported and registered elements is required.
  • *
  • The natural order should be consistent with {@code equals()}.
  • *
* * @param generic type of self reference * @author Meno Hochschild * @serial exclude * @since 3.4/4.3 * @see Chronology * @see CalendarFamily */ /*[deutsch] *

Repräsentiert eine unveränderlichen Kalendervariante.

* *

Chronologische Elementwerte anzeigen und ändern

* *

Der Zeitwert setzt sich aus chronologischen Elementen zusammen. Diese * abstrakte Basisklasse delegiert die Zeitrechnung immer an die zugehörige * Kalenderfamilie bzw. genauer an die ihr zugeordneten Regeln der Elemente, muß aber * selbst den Zustand definieren, in den {@code get()}-Methoden den Zustand reflektieren und * auch das Serialisierungsverhalten festlegen.

* *

Da alle konkreten Implementierungen immutable sind und sein * müssen, sind Elementwerte nur dadurch änderbar, daß jeweils * eine neue Instanz mit geänderten Elementwerten erzeugt wird. Das wird * unter anderem von allen {@code with()}-Methoden geleistet.

* *

Kalendersystem

* *

Jede Kalendervariante gehört zu einer Kalenderfamilie. Das schließt den * den Bezug zu einem Kalendersystem mit Hilfe eines Variantennamens ein. Daher ist eine * begrenzte Zeitarithmetick auf Tageseinheiten basierend immer möglich.

* *

Sortierung

* *

Die Sortierung von Kalendervarianten wird die zeitliche Ordnung bevorzugen * und dann die lexikalische Ordnung von Variantennamen. Im Zweifelsfall ist die Dokumentation der * konkreten Subklasse maßgeblich. Alternativ kann auch das Interface {@code Temporal} * verwendet werden, um eine rein zeitliche Ordnung zu ermöglichen.

* *

Implementierungshinweise

* *
    *
  • Alle Subklassen müssen final und immutable sein.
  • *
  • Es muß dokumentiert werden, welche chronologischen Elemente * unterstützt werden bzw. registriert sind.
  • *
  • Die natürliche Ordnung sollte konsistent mit {@code equals()} * sein.
  • *
* * @param generic type of self reference * @author Meno Hochschild * @serial exclude * @since 3.4/4.3 * @see Chronology * @see CalendarFamily */ public abstract class CalendarVariant> extends ChronoEntity implements CalendarDate, Comparable, Serializable { //~ Methoden ---------------------------------------------------------- /** *

Returns the name of the associated variant of underlying calendar system.

* * @return String * @since 3.4/4.3 * @see CalendarFamily#getCalendarSystem(String) */ /*[deutsch] *

Liefert den Namen der assoziierten Variante des zugrundeliegenden Kalendersystems.

* * @return String * @since 3.4/4.3 * @see CalendarFamily#getCalendarSystem(String) */ public abstract String getVariant(); /** *

Creates a copy of this instance with given variant.

* *

If given variant is equal to the variant of this instance * then the method will just return this instance.

* * @param variant name of new variant * @return copy of this instance with equal epoch-day-value but different variant * @throws ChronoException if given variant is not supported * @since 3.14/4.11 */ /*[deutsch] *

Erzeugt eine Kopie dieser Instanz mit der angegebenen Variante.

* *

Wenn die angegebene Variante der Variante dieser Instanz gleicht, wird die * Methode einfach nur diese Instanz zurückgeben.

* * @param variant name of new variant * @return copy of this instance with equal epoch-day-value but different variant * @throws ChronoException if given variant is not supported * @since 3.14/4.11 */ public D withVariant(String variant) { if (variant.equals(this.getVariant())) { // NPE-check return this.getContext(); } return this.transform(this.getChronology().getChronoType(), variant); } /** *

Equivalent to {@link #withVariant(String) withVariant(variantSource.getVariant())}.

* * @param variantSource source of desired calendar variant * @return copy of this instance with equal epoch-day-value but different variant * @since 3.14/4.11 */ /*[deutsch] *

Äquivalent zu {@link #withVariant(String) withVariant(variantSource.getVariant())}.

* * @param variantSource source of desired calendar variant * @return copy of this instance with equal epoch-day-value but different variant * @since 3.14/4.11 */ public D withVariant(VariantSource variantSource) { return this.withVariant(variantSource.getVariant()); } /** *

Compares two calendar variants preferably by their temporal positions * on the common date axis and then by their variant names.

* *

Implementation note: In order to make the natural order consistent * with {@code equals()} the whole state must be taken into account, * with preference for those attributes which define the temporal * position on the time axis.

* * @param calendarVariant the object to be compared. * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. * @see #equals(Object) */ /*[deutsch] *

Vergleicht zwei Kalendervarianten bevorzugt nach ihrer Position auf der * gemeinsamen Zeitachse und dann lexikalisch nach ihren Variantennamen.

* *

Implementierungshinweis: Damit die natürliche Ordnung konsistent * mit {@code equals()} ist, müssen zum Vergleich alle internen * Zustandsattribute herangezogen werden, bevorzugt aber die Attribute, * die die zeitliche Position festlegen.

* * @param calendarVariant the object to be compared. * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. * @see #equals(Object) */ @Override public int compareTo(D calendarVariant) { long t1 = this.getDaysSinceEpochUTC(); long t2 = calendarVariant.getDaysSinceEpochUTC(); if (t1 < t2) { return - 1; } else if (t1 > t2) { return 1; } else { return this.getVariant().compareTo(calendarVariant.getVariant()); } } @Override public boolean isAfter(CalendarDate other) { long t1 = this.getDaysSinceEpochUTC(); long t2 = other.getDaysSinceEpochUTC(); return (t1 > t2); } @Override public boolean isBefore(CalendarDate other) { long t1 = this.getDaysSinceEpochUTC(); long t2 = other.getDaysSinceEpochUTC(); return (t1 < t2); } @Override public boolean isSimultaneous(CalendarDate other) { long t1 = this.getDaysSinceEpochUTC(); long t2 = other.getDaysSinceEpochUTC(); return (t1 == t2); } /** *

Adds given calendar days to this instance.

* * @param days calendar days to be added * @return result of addition * @throws ArithmeticException in case of numerical overflow * @since 3.4/4.3 */ /*[deutsch] *

Addiert die angegebenen Kalendertage zu dieser Instanz.

* * @param days calendar days to be added * @return result of addition * @throws ArithmeticException in case of numerical overflow * @since 3.4/4.3 */ public D plus(CalendarDays days) { long result = Math.addExact(this.getDaysSinceEpochUTC(), days.getAmount()); try { return this.getCalendarSystem().transform(result); } catch (IllegalArgumentException iae) { ArithmeticException ex = new ArithmeticException("Out of range: " + result); ex.initCause(iae); throw ex; } } /** *

Subtracts given calendar days from this instance.

* * @param days calendar days to be subtracted * @return result of subtraction * @throws ArithmeticException in case of numerical overflow * @since 3.4/4.3 */ /*[deutsch] *

Subtrahiert die angegebenen Kalendertage von dieser Instanz.

* * @param days calendar days to be subtracted * @return result of subtraction * @throws ArithmeticException in case of numerical overflow * @since 3.4/4.3 */ public D minus(CalendarDays days) { return this.plus(CalendarDays.of(Math.negateExact(days.getAmount()))); } /** *

Compares the whole state of this instance with given object.

* *

Implementations will usually define their state based on the temporal position * and the variant name. Exceptions from this rule should be explicitly documented and reasoned.

* * @see #compareTo(CalendarVariant) */ /*[deutsch] *

Vergleicht den gesamten Zustand dieser Instanz mit dem des angegebenen Objekts.

* *

Implementierungen werden üblicherweise ihren Zustand auf Basis der zeitlichen Position * und der Variantennamen definieren, da dies am ehesten der Erwartungshaltung der Anwender entspricht. * Ausnahmen sind explizit zu dokumentieren und zu begründen.

* * @see #compareTo(TimePoint) */ @Override public abstract boolean equals(Object obj); /** *

Subclasses must redefine this method corresponding to the * behaviour of {@code equals()}.

*/ /*[deutsch] *

Subklassen müssen diese Methode passend zum Verhalten * von {@code equals()} redefinieren.

*/ @Override public abstract int hashCode(); /** *

Provides a complete textual representation of the state of this calendar variant.

*/ /*[deutsch] *

Liefert eine vollständige Beschreibung des Zustands dieser Kalendervariante.

*/ @Override public abstract String toString(); @Override public long getDaysSinceEpochUTC() { return this.getCalendarSystem().transform(this.getContext()); } /** *

Returns the assigned calendar family which contains all necessary * chronological rules.

* *

Concrete subclasses must create in a static initializer a * calendar family by help of {@code CalendarFamily.Builder}, keep it as static * constant and make it available here. Using the procedure guarantees * that a basic set of registered elements and rules will be installed.

* * @return chronological system as calendar family (never {@code null}) * @since 3.4/4.3 * @see CalendarFamily.Builder */ /*[deutsch] *

Liefert die zugehörige Kalenderfamilie, die alle notwendigen * chronologischen Regeln enthält.

* *

Konkrete Subklassen müssen in einem static initializer * mit Hilfe von {@code CalendarFamily.Builder} eine Kalenderfamilie bauen, in * einer eigenen Konstanten halten und hier verfügbar machen. * Über dieses Verfahren wird zugleich ein Basissatz von Elementen * und chronologischen Regeln vorinstalliert.

* * @return chronological system as calendar family (never {@code null}) * @since 3.4/4.3 * @see CalendarFamily.Builder */ @Override protected abstract CalendarFamily getChronology(); @SuppressWarnings("unchecked") @Override ElementRule getRule(ChronoElement element) { if (element instanceof EpochDays) { EpochDays ed = EpochDays.class.cast(element); return (ElementRule) ed.derive(this.getCalendarSystem()); } else { return super.getRule(element); } } private CalendarSystem getCalendarSystem() { return this.getChronology().getCalendarSystem(this.getVariant()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy