net.time4j.tz.TransitionHistory Maven / Gradle / Ivy
/*
* -----------------------------------------------------------------------
* Copyright © 2013-2017 Meno Hochschild,
* -----------------------------------------------------------------------
* This file (TransitionHistory.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.tz;
import net.time4j.base.GregorianDate;
import net.time4j.base.UnixTime;
import net.time4j.base.WallTime;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
/**
* Keeps all offset transitions and rules of a timezone.
*
* Note: This interface can be considered as stable since version v2.2.
* Preliminary experimental versions of this interface existed since v1.0
* but there was originally not any useable implementation.
*
* @author Meno Hochschild
* @doctags.spec All implementations must be immutable, thread-safe and serializable.
*/
/*[deutsch]
* Hält alle Übergänge und Regeln einer Zeitzone.
*
* Hinweis: Dieses Interface kann als stabil seit Version 2.2 gelten.
* Davor existierten experimentelle Versionen des Interface schon seit v1.0,
* aber es gab ursprünglich keine nutzbare Implementierung.
*
* @author Meno Hochschild
* @doctags.spec All implementations must be immutable, thread-safe and serializable.
*/
public interface TransitionHistory {
//~ Methoden ----------------------------------------------------------
/**
* Return the initial offset no matter if there are any
* transitions defined or not.
*
* If any transition is defined then the initial offset
* is identical to the shift {@code getPreviousOffset()} of
* the first defined transition in history.
*
* @return fixed initial shift in full seconds
*/
/*[deutsch]
* Ermittelt die initiale Verschiebung unabhängig davon, ob es
* Übergänge gibt oder nicht.
*
* Falls es Übergänge gibt, muß die initiale
* Verschiebung mit der Verschiebung {@code getPreviousOffset()}
* des ersten definierten Übergangs identisch sein.
*
* @return fixed initial shift in full seconds
*/
ZonalOffset getInitialOffset();
/**
* Queries the last transition which defines the offset
* for given global timestamp.
*
* For standard use cases, users can use the alternative method
* {@code findStartTransition()} unless performance considerations prohibit
* the usage of class {@code Optional}.
*
* @param ut unix reference time
* @return {@code ZonalTransition} or {@code null} if given reference time is before first defined transition
* @see #findStartTransition(UnixTime)
*/
/*[deutsch]
* Ermittelt den letzten Übergang, der die zur angegebenen
* Referenzzeit zugehörige Verschiebung definiert.
*
* Für Standardfälle können Anwender die alternative Methode
* {@code findStartTransition()} verwenden, es sei denn, Performance-Aspekte
* verbieten den Gebrauch der Klasse {@code Optional}.
*
* @param ut unix reference time
* @return {@code ZonalTransition} or {@code null} if given reference time is before first defined transition
* @see #findStartTransition(UnixTime)
*/
ZonalTransition getStartTransition(UnixTime ut);
/**
* Returns the conflict transition where given local timestamp
* falls either in a gap or in an overlap on the local timeline.
*
* Note that only the expression {@code localDate.getYear()} is used
* to determine the daylight saving rules to be applied in calculation.
* This is particularly important if there is a wall time of 24:00. Here
* only the date before merging to next day matters, not the date of the
* whole timestamp.
*
* For standard use cases, users can use the alternative method
* {@code findConflictTransition()} unless performance considerations prohibit
* the usage of class {@code Optional}.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return conflict transition on the local time axis for gaps or overlaps else {@code null}
* @see #getValidOffsets(GregorianDate,WallTime)
* @see #findConflictTransition(GregorianDate, WallTime)
*/
/*[deutsch]
* Bestimmt den passenden Übergang, wenn die angegebene lokale
* Zeit in eine Lücke oder eine Überlappung auf dem lokalen
* Zeitstrahl fällt.
*
* Zu beachten: Nur der Ausdruck {@code localDate.getYear()} wird
* in der Ermittlung der passenden DST-Regeln benutzt. Das ist insbesondere
* von Bedeutung, wenn die Uhrzeit 24:00 vorliegt. Hier zählt nur
* das Jahr des angegebenen Datums, nicht das des Zeitstempels, der
* wegen der Uhrzeit evtl. im Folgejahr liegt.
*
* Für Standardfälle können Anwender die alternative Methode
* {@code findConflictTransition()} verwenden, es sei denn, Performance-Aspekte
* verbieten den Gebrauch der Klasse {@code Optional}.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return conflict transition on the local time axis for gaps or overlaps else {@code null}
* @see #getValidOffsets(GregorianDate,WallTime)
* @see #findConflictTransition(GregorianDate, WallTime)
*/
ZonalTransition getConflictTransition(
GregorianDate localDate,
WallTime localTime
);
/**
* Queries the next transition after given global timestamp.
*
* @param ut unix reference time
* @return {@code ZonalTransition} or {@code null} if given reference time
* is after any defined transition
* @deprecated Use the equivalent {@link #findNextTransition(UnixTime)}
*/
/*[deutsch]
* Ermittelt den nächsten Übergang nach der angegebenen
* Referenzzeit.
*
* @param ut unix reference time
* @return {@code ZonalTransition} or {@code null} if given reference time
* is after any defined transition
* @deprecated Use the equivalent {@link #findNextTransition(UnixTime)}
*/
@Deprecated
ZonalTransition getNextTransition(UnixTime ut);
/**
* Determines the suitable offsets at given local timestamp..
*
* The offset list is empty if the local timestamp falls in a gap
* on the local timeline. The list has exactly two offsets sorted by size
* if the local timestamp belongs to two different timepoints on the
* POSIX timescale due to an overlap. Otherwise the offset list
* will contain exactly one suitable offset.
*
* Note that only the expression {@code localDate.getYear()} is used
* to determine the daylight saving rules to be applied in calculation.
* This is particularly important if there is a wall time of 24:00. Here
* only the date before merging to next day matters, not the date of the
* whole timestamp.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return unmodifiable list of shifts in full seconds which fits the
* given local time
* @see #findConflictTransition(GregorianDate,WallTime)
*/
/*[deutsch]
* Bestimmt die zur angegebenen lokalen Zeit passenden
* zonalen Verschiebungen.
*
* Die Liste ist leer, wenn die lokale Zeit in eine Lücke auf
* dem lokalen Zeitstrahl fällt. Die Liste hat genau zwei nach
* Größe sortierte Verschiebungen, wenn die lokale Zeit wegen
* einer Überlappung zu zwei verschiedenen Zeitpunkten auf der
* POSIX-Zeitskala gehört. Ansonsten wird die Liste genau eine
* passende Verschiebung enthalten.
*
* Zu beachten: Nur der Ausdruck {@code localDate.getYear()} wird
* in der Ermittlung der passenden DST-Regeln benutzt. Das ist insbesondere
* von Bedeutung, wenn die Uhrzeit 24:00 vorliegt. Hier zählt nur
* das Jahr des angegebenen Datums, nicht das des Zeitstempels, der
* wegen der Uhrzeit evtl. im Folgejahr liegt.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return unmodifiable list of shifts in full seconds which fits the
* given local time
* @see #findConflictTransition(GregorianDate,WallTime)
*/
List getValidOffsets(
GregorianDate localDate,
WallTime localTime
);
/**
* Return the offset transitions from UNIX epoch [1970-01-01T00:00Z]
* until about one year after the current timestamp.
*
* Indeed, a potentially bigger interval is obtainable by
* {@link #getTransitions(UnixTime,UnixTime)}, but earlier or
* later timepoints are usually not reliable. For example the
* wide-spread IANA/Olson-repository is only designed for times
* since UNIX epoch and offers some selected older data to the
* best of our knowledge. Users must be aware that even older
* data can be changed as side effect of data corrections. Generally
* the timezone concept was invented in 19th century. And future
* transitions are even less reliable due to political arbitrariness.
*
* @return unmodifiable list of standard transitions (after 1970-01-01)
* maybe empty
*/
/*[deutsch]
* Bestimmt alle vorhandenen zonalen Übergänge ab der
* UNIX-Epoche [1970-01-01T00:00Z] bis zirka ein Jahr nach dem aktuellen
* heutigen Zeitpunkt.
*
* Zwar kann mittels {@link #getTransitions(UnixTime,UnixTime)}
* auch ein potentiell größeres Intervall abgefragt werden,
* jedoch sind frühere oder spätere Zeitpunkte in aller Regel
* mit großen Unsicherheiten verknüpft. Zum Beispiel ist die
* weithin verwendete IANA/Olson-Zeitzonendatenbank nur für Zeiten
* ab der UNIX-Epoche gedacht und bietet ausgewählte ältere
* Zeitzonendaten lediglich nach bestem Wissen und Gewissen an. Anwender
* müssen beachten, daß sich sogar historische alte Daten
* nachträglich ändern können. Generell existiert das
* Zeitzonenkonzept erst ab ca. dem 19. Jahrhundert. Und in der Zukunft
* liegende Zeitzonenänderungen sind wegen politischer Willkür
* sogar noch unsicherer.
*
* @return unmodifiable list of standard transitions (after 1970-01-01)
* maybe empty
*/
List getStdTransitions();
/**
* Returns the defined transitions in given POSIX-interval.
*
* @param startInclusive start time on POSIX time scale
* @param endExclusive end time on POSIX time scale
* @return unmodifiable list of transitions maybe empty
* @throws IllegalArgumentException if start is after end
* @see #getStdTransitions()
*/
/*[deutsch]
* Bestimmt die im angegebenen POSIX-Intervall vorhandenen zonalen
* Übergänge.
*
* @param startInclusive start time on POSIX time scale
* @param endExclusive end time on POSIX time scale
* @return unmodifiable list of transitions maybe empty
* @throws IllegalArgumentException if start is after end
* @see #getStdTransitions()
*/
List getTransitions(
UnixTime startInclusive,
UnixTime endExclusive
);
/**
* Determines if this history does not have any transitions.
*
* @return {@code true} if there are no transitions else {@code false}
*/
/*[deutsch]
* Ermittelt ob diese Historie keine Übergänge kennt.
*
* @return {@code true} if there are no transitions else {@code false}
*/
boolean isEmpty();
/**
* Creates a dump of this history and writes it to the given buffer.
*
* @param buffer buffer to write the dump to
* @throws IOException in any case of I/O-errors
*/
/*[deutsch]
* Erzeugt eine Textzusammenfassung dieser Instanz und schreibt sie
* in den angegebenen Puffer.
*
* @param buffer buffer to write the dump to
* @throws IOException in any case of I/O-errors
*/
void dump(Appendable buffer) throws IOException;
/**
* Queries the last transition which defines the offset
* for given global timestamp.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is before first defined transition
* @since 4.18
*/
/*[deutsch]
* Ermittelt den letzten Übergang, der die zur angegebenen
* Referenzzeit zugehörige Verschiebung definiert.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is before first defined transition
* @since 4.18
*/
default Optional findStartTransition(UnixTime ut) {
ZonalTransition transition = this.getStartTransition(ut);
return ((transition == null) ? Optional.empty() : Optional.of(transition));
}
/**
* Returns the conflict transition where given local timestamp
* falls either in a gap or in an overlap on the local timeline.
*
* Note that only the expression {@code localDate.getYear()} is used
* to determine the daylight saving rules to be applied in calculation.
* This is particularly important if there is a wall time of 24:00. Here
* only the date before merging to next day matters, not the date of the
* whole timestamp.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return optional conflict transition on the local time axis for gaps or overlaps if present
* @see #getValidOffsets(GregorianDate,WallTime)
* @since 4.18
*/
/*[deutsch]
* Bestimmt den passenden Übergang, wenn die angegebene lokale
* Zeit in eine Lücke oder eine Überlappung auf dem lokalen
* Zeitstrahl fällt.
*
* Zu beachten: Nur der Ausdruck {@code localDate.getYear()} wird
* in der Ermittlung der passenden DST-Regeln benutzt. Das ist insbesondere
* von Bedeutung, wenn die Uhrzeit 24:00 vorliegt. Hier zählt nur
* das Jahr des angegebenen Datums, nicht das des Zeitstempels, der
* wegen der Uhrzeit evtl. im Folgejahr liegt.
*
* @param localDate local date in timezone
* @param localTime local wall time in timezone
* @return optional conflict transition on the local time axis for gaps or overlaps if present
* @see #getValidOffsets(GregorianDate,WallTime)
* @since 4.18
*/
default Optional findConflictTransition(
GregorianDate localDate,
WallTime localTime
) {
ZonalTransition transition = this.getConflictTransition(localDate, localTime);
return ((transition == null) ? Optional.empty() : Optional.of(transition));
}
/**
* Queries the next transition after given global timestamp.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is after any defined transition
* @since 4.18
*/
/*[deutsch]
* Ermittelt den nächsten Übergang nach der angegebenen
* Referenzzeit.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is after any defined transition
* @since 4.18
*/
default Optional findNextTransition(UnixTime ut) {
throw new UnsupportedOperationException("Not yet implemented.");
}
/**
* Queries the previous transition which defines the offset
* for a global timestamp immediately before given reference timestamp.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is not after any defined transition
* @since 4.18
*/
/*[deutsch]
* Ermittelt den vorherigen Übergang, der die unmittelbar vor der angegebenen
* Referenzzeit zugehörige Verschiebung definiert.
*
* @param ut unix reference time
* @return {@code ZonalTransition}, not present if given reference time is not after any defined transition
* @since 4.18
*/
default Optional findPreviousTransition(final UnixTime ut) {
return this.findStartTransition(
new UnixTime() {
@Override
public long getPosixTime() {
return ((ut.getNanosecond() == 0) ? (ut.getPosixTime() - 1) : ut.getPosixTime());
}
@Override
public int getNanosecond() {
return ((ut.getNanosecond() == 0) ? 999_999_999 : (ut.getNanosecond() - 1));
}
}
);
}
}