001/*
002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos
003 *
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 *  * Redistributions of source code must retain the above copyright notice,
010 *    this list of conditions and the following disclaimer.
011 *
012 *  * Redistributions in binary form must reproduce the above copyright notice,
013 *    this list of conditions and the following disclaimer in the documentation
014 *    and/or other materials provided with the distribution.
015 *
016 *  * Neither the name of JSR-310 nor the names of its contributors
017 *    may be used to endorse or promote products derived from this software
018 *    without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032package org.threeten.bp.temporal;
033
034import java.util.Comparator;
035
036import org.threeten.bp.DateTimeException;
037import org.threeten.bp.Instant;
038import org.threeten.bp.LocalTime;
039import org.threeten.bp.ZoneId;
040import org.threeten.bp.ZoneOffset;
041import org.threeten.bp.ZonedDateTime;
042import org.threeten.bp.format.DateTimeFormatter;
043
044/**
045 * A date-time with a time-zone in an arbitrary chronology,
046 * intended for advanced globalization use cases.
047 * <p>
048 * <b>Most applications should declare method signatures, fields and variables
049 * as {@link ZonedDateTime}, not this interface.</b>
050 * <p>
051 * A {@code ChronoZonedDateTime} is the abstract representation of an offset date-time
052 * where the {@code Chrono chronology}, or calendar system, is pluggable.
053 * The date-time is defined in terms of fields expressed by {@link TemporalField},
054 * where most common implementations are defined in {@link ChronoField}.
055 * The chronology defines how the calendar system operates and the meaning of
056 * the standard fields.
057 *
058 * <h4>When to use this interface</h4>
059 * The design of the API encourages the use of {@code ZonedDateTime} rather than this
060 * interface, even in the case where the application needs to deal with multiple
061 * calendar systems. The rationale for this is explored in detail in {@link ChronoLocalDate}.
062 * <p>
063 * Ensure that the discussion in {@code ChronoLocalDate} has been read and understood
064 * before using this interface.
065 *
066 * <h3>Specification for implementors</h3>
067 * This interface must be implemented with care to ensure other classes operate correctly.
068 * All implementations that can be instantiated must be final, immutable and thread-safe.
069 * Subclasses should be Serializable wherever possible.
070 *
071 * @param <C> the chronology of this date-time
072 */
073public interface ChronoZonedDateTime<C extends Chrono<C>>
074        extends Temporal, Comparable<ChronoZonedDateTime<?>> {
075
076    /**
077     * Comparator for two {@code ChronoZonedDateTime} instances ignoring the chronology.
078     * <p>
079     * This method differs from the comparison in {@link #compareTo} in that it
080     * only compares the underlying date and not the chronology.
081     * This allows dates in different calendar systems to be compared based
082     * on the time-line position.
083     *
084     * @see #isAfter
085     * @see #isBefore
086     * @see #isEqual
087     */
088    Comparator<ChronoZonedDateTime<?>> INSTANT_COMPARATOR = new Comparator<ChronoZonedDateTime<?>>() {
089        @Override
090        public int compare(ChronoZonedDateTime<?> datetime1, ChronoZonedDateTime<?> datetime2) {
091            int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
092            if (cmp == 0) {
093                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
094            }
095            return cmp;
096        }
097    };
098
099    /**
100     * Gets the local date part of this date-time.
101     * <p>
102     * This returns a local date with the same year, month and day
103     * as this date-time.
104     *
105     * @return the date part of this date-time, not null
106     */
107    ChronoLocalDate<C> getDate() ;
108
109    /**
110     * Gets the local time part of this date-time.
111     * <p>
112     * This returns a local time with the same hour, minute, second and
113     * nanosecond as this date-time.
114     *
115     * @return the time part of this date-time, not null
116     */
117    LocalTime getTime();
118
119    /**
120     * Gets the local date-time part of this date-time.
121     * <p>
122     * This returns a local date with the same year, month and day
123     * as this date-time.
124     *
125     * @return the local date-time part of this date-time, not null
126     */
127    ChronoLocalDateTime<C> getDateTime();
128
129    /**
130     * Gets the zone offset, such as '+01:00'.
131     * <p>
132     * This is the offset of the local date-time from UTC/Greenwich.
133     *
134     * @return the zone offset, not null
135     */
136    ZoneOffset getOffset();
137
138    /**
139     * Gets the zone ID, such as 'Europe/Paris'.
140     * <p>
141     * This returns the stored time-zone id used to determine the time-zone rules.
142     *
143     * @return the zone ID, not null
144     */
145    ZoneId getZone();
146
147    //-----------------------------------------------------------------------
148    /**
149     * Returns a copy of this date-time changing the zone offset to the
150     * earlier of the two valid offsets at a local time-line overlap.
151     * <p>
152     * This method only has any effect when the local time-line overlaps, such as
153     * at an autumn daylight savings cutover. In this scenario, there are two
154     * valid offsets for the local date-time. Calling this method will return
155     * a zoned date-time with the earlier of the two selected.
156     * <p>
157     * If this method is called when it is not an overlap, {@code this}
158     * is returned.
159     * <p>
160     * This instance is immutable and unaffected by this method call.
161     *
162     * @return a {@code ZoneChronoDateTime} based on this date-time with the earlier offset, not null
163     * @throws DateTimeException if no rules can be found for the zone
164     * @throws DateTimeException if no rules are valid for this date-time
165     */
166    ChronoZonedDateTime<C> withEarlierOffsetAtOverlap();
167
168    /**
169     * Returns a copy of this date-time changing the zone offset to the
170     * later of the two valid offsets at a local time-line overlap.
171     * <p>
172     * This method only has any effect when the local time-line overlaps, such as
173     * at an autumn daylight savings cutover. In this scenario, there are two
174     * valid offsets for the local date-time. Calling this method will return
175     * a zoned date-time with the later of the two selected.
176     * <p>
177     * If this method is called when it is not an overlap, {@code this}
178     * is returned.
179     * <p>
180     * This instance is immutable and unaffected by this method call.
181     *
182     * @return a {@code ChronoZonedDateTime} based on this date-time with the later offset, not null
183     * @throws DateTimeException if no rules can be found for the zone
184     * @throws DateTimeException if no rules are valid for this date-time
185     */
186    ChronoZonedDateTime<C> withLaterOffsetAtOverlap();
187
188    //-----------------------------------------------------------------------
189    /**
190     * Returns a copy of this ZonedDateTime with a different time-zone,
191     * retaining the local date-time if possible.
192     * <p>
193     * This method changes the time-zone and retains the local date-time.
194     * The local date-time is only changed if it is invalid for the new zone.
195     * <p>
196     * To change the zone and adjust the local date-time,
197     * use {@link #withZoneSameInstant(ZoneId)}.
198     * <p>
199     * This instance is immutable and unaffected by this method call.
200     *
201     * @param zoneId  the time-zone to change to, not null
202     * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null
203     */
204    ChronoZonedDateTime<C> withZoneSameLocal(ZoneId zoneId);
205
206    /**
207     * Returns a copy of this date-time with a different time-zone,
208     * retaining the instant.
209     * <p>
210     * This method changes the time-zone and retains the instant.
211     * This normally results in a change to the local date-time.
212     * <p>
213     * This method is based on retaining the same instant, thus gaps and overlaps
214     * in the local time-line have no effect on the result.
215     * <p>
216     * To change the offset while keeping the local time,
217     * use {@link #withZoneSameLocal(ZoneId)}.
218     *
219     * @param zoneId  the time-zone to change to, not null
220     * @return a {@code ChronoZonedDateTime} based on this date-time with the requested zone, not null
221     * @throws DateTimeException if the result exceeds the supported date range
222     */
223    ChronoZonedDateTime<C> withZoneSameInstant(ZoneId zoneId);
224
225    //-------------------------------------------------------------------------
226    // override for covariant return type
227    @Override
228    ChronoZonedDateTime<C> with(TemporalAdjuster adjuster);
229
230    @Override
231    ChronoZonedDateTime<C> with(TemporalField field, long newValue);
232
233    @Override
234    ChronoZonedDateTime<C> plus(TemporalAdder adjuster);
235
236    @Override
237    ChronoZonedDateTime<C> plus(long amountToAdd, TemporalUnit unit);
238
239    @Override
240    ChronoZonedDateTime<C> minus(TemporalSubtractor adjuster);
241
242    @Override
243    ChronoZonedDateTime<C> minus(long amountToSubtract, TemporalUnit unit);
244
245    //-----------------------------------------------------------------------
246    /**
247     * Converts this date-time to an {@code Instant}.
248     * <p>
249     * This combines the {@link #getDateTime() local date-time} and
250     * {@link #getOffset() offset} to form an {@code Instant}.
251     *
252     * @return an {@code Instant} representing the same instant, not null
253     */
254    Instant toInstant();
255
256    /**
257     * Converts this date-time to the number of seconds from the epoch
258     * of 1970-01-01T00:00:00Z.
259     * <p>
260     * This uses the {@link #getDateTime() local date-time} and
261     * {@link #getOffset() offset} to calculate the epoch-second value,
262     * which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
263     * Instants on the time-line after the epoch are positive, earlier are negative.
264     *
265     * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
266     */
267    long toEpochSecond();
268
269    //-----------------------------------------------------------------------
270    /**
271     * Compares this date-time to another date-time, including the chronology.
272     * <p>
273     * The comparison is based first on the instant, then on the local date-time,
274     * then on the zone ID, then on the chronology.
275     * It is "consistent with equals", as defined by {@link Comparable}.
276     * <p>
277     * If all the date-time objects being compared are in the same chronology, then the
278     * additional chronology stage is not required.
279     *
280     * @param other  the other date-time to compare to, not null
281     * @return the comparator value, negative if less, positive if greater
282     */
283    @Override
284    int compareTo(ChronoZonedDateTime<?> other);
285
286    //-----------------------------------------------------------------------
287    /**
288     * Checks if the instant of this date-time is before that of the specified date-time.
289     * <p>
290     * This method differs from the comparison in {@link #compareTo} in that it
291     * only compares the instant of the date-time. This is equivalent to using
292     * {@code dateTime1.toInstant().isBefore(dateTime2.toInstant());}.
293     *
294     * @param other  the other date-time to compare to, not null
295     * @return true if this point is before the specified date-time
296     */
297    boolean isBefore(ChronoZonedDateTime<?> other);
298
299    /**
300     * Checks if the instant of this date-time is after that of the specified date-time.
301     * <p>
302     * This method differs from the comparison in {@link #compareTo} in that it
303     * only compares the instant of the date-time. This is equivalent to using
304     * {@code dateTime1.toInstant().isAfter(dateTime2.toInstant());}.
305     *
306     * @param other  the other date-time to compare to, not null
307     * @return true if this is after the specified date-time
308     */
309    boolean isAfter(ChronoZonedDateTime<?> other);
310
311    /**
312     * Checks if the instant of this date-time is equal to that of the specified date-time.
313     * <p>
314     * This method differs from the comparison in {@link #compareTo} and {@link #equals}
315     * in that it only compares the instant of the date-time. This is equivalent to using
316     * {@code dateTime1.toInstant().equals(dateTime2.toInstant());}.
317     *
318     * @param other  the other date-time to compare to, not null
319     * @return true if the instant equals the instant of the specified date-time
320     */
321    boolean isEqual(ChronoZonedDateTime<?> other);
322
323    //-----------------------------------------------------------------------
324    /**
325     * Checks if this date-time is equal to another date-time.
326     * <p>
327     * The comparison is based on the offset date-time and the zone.
328     * To compare for the same instant on the time-line, use {@link #compareTo}.
329     * Only objects of type {@code ChronoZoneDateTime} are compared, other types return false.
330     *
331     * @param obj  the object to check, null returns false
332     * @return true if this is equal to the other date-time
333     */
334    @Override
335    boolean equals(Object obj);
336
337    /**
338     * A hash code for this date-time.
339     *
340     * @return a suitable hash code
341     */
342    @Override
343    int hashCode();
344
345    //-----------------------------------------------------------------------
346    /**
347     * Outputs this date-time as a {@code String}.
348     * <p>
349     * The output will include the full zoned date-time and the chronology ID.
350     *
351     * @return a string representation of this date-time, not null
352     */
353    @Override
354    String toString();
355
356    /**
357     * Outputs this date-time as a {@code String} using the formatter.
358     *
359     * @param formatter  the formatter to use, not null
360     * @return the formatted date-time string, not null
361     * @throws DateTimeException if an error occurs during printing
362     */
363    String toString(DateTimeFormatter formatter) ;
364
365}